package astrologer_routes

import (
	config "astrology-api/configs"
	astrologerController "astrology-api/controllers/astrologer"
	usercontroller "astrology-api/controllers/user"
	middleware "astrology-api/middleware"
	"astrology-api/notifications"
	"astrology-api/repositories"
	repositories_astrologer "astrology-api/repositories_astrologer"
	"astrology-api/services"
	services_astrologer "astrology-api/services_astrologer"

	"github.com/gin-gonic/gin"
)

func RegisterAstrologerRoutes(router *gin.RouterGroup) {

	authController := astrologerController.NewAuthController()

	astrologerRepo := repositories_astrologer.NewAstrologerRepository()

	dashboardRepo := repositories_astrologer.NewDashboardRepository()
	statusRepo := repositories_astrologer.NewStatusRepository()
	statisticsRepo := repositories_astrologer.NewStatisticsRepository()
	offerRepo := repositories_astrologer.NewOfferRepository()
	restTimeRepo := repositories_astrologer.NewRestTimeRepository()
	statusLogRepo := repositories_astrologer.NewStatusLogRepository()
	// Service
	astrologerService := services_astrologer.NewAstrologerService(astrologerRepo)
	dashboardService := services_astrologer.NewDashboardService(dashboardRepo, statusRepo, statisticsRepo, offerRepo, restTimeRepo, statusLogRepo)
	// Controller
	profileController := astrologerController.NewAstrologerController(astrologerService)
	dashboardController := astrologerController.NewDashboardController(dashboardService)
	walletRepository := repositories_astrologer.NewWalletRepository(config.DB)
	walletService := services_astrologer.NewWalletService(walletRepository)
	walletController := astrologerController.NewWalletController(walletService)
	settlementController := astrologerController.NewSettlementController(walletService)
	consultationRepository := repositories.NewConsultationRepository(config.DB)

	consultationService := services.NewConsultationService(
		consultationRepository,
		services.NewAgoraTokenService(config.Agora),
	)

	consultationController := astrologerController.NewConsultationController(consultationService)

	consultationMessageController := astrologerController.NewConsultationMessageController(
		services.NewConsultationMessageService(consultationRepository),
	)
	activityRepository := repositories_astrologer.NewActivityRepository(config.DB)
	activityService := services_astrologer.NewActivityService(activityRepository)
	activityController := astrologerController.NewActivityController(activityService)

	// Same notifications.Center as the user routes: one table, one set of
	// semantics, keyed on the astrologer's users.id.
	notificationController := astrologerController.NewNotificationController(
		notifications.NewCenter(config.DB),
	)

	// The customer's horoscope service; astrologers are logged but never charged.
	horoscopeController := astrologerController.NewHoroscopeController(services.NewHoroscopeService())

	// The customer app's astrology services, for the astrologer app. The
	// handlers are the customer ones - same requests, same responses - over the
	// *ForAstrologer services, which never charge: on this side the token's
	// users.id is the astrologer's own earnings wallet. Only services the admin
	// catalogue marks astrologer_enabled are mounted (no save / list / delete).
	kundaliController := usercontroller.NewKundaliController()
	matchingController := usercontroller.NewMatchingController(services.NewMatchingServiceForAstrologer())
	panchangController := usercontroller.NewPanchangController(services.NewPanchangServiceForAstrologer())
	numerologyController := usercontroller.NewNumerologyController(services.NewNumerologyServiceForAstrologer())
	tarotController := usercontroller.NewTarotController(services.NewTarotServiceForAstrologer())

	// Hits go to astrology_service_usage as ASTROLOGER, like the customer side.
	track := middleware.TrackAstrologyService(middleware.AstrologerSide)

	api := router.Group("/astrologer")
	{
		api.POST("/register", authController.Register)

		api.POST("/verify-mobile", authController.VerifyMobileOTP)

		api.POST("/verify-email", authController.VerifyEmailOTP)

		api.POST("/resend-otp", authController.ResendOTP)

		api.POST("/login", authController.Login)

		api.POST("/verify-login", authController.VerifyLoginOTP)

		api.POST("/refresh-token", authController.RefreshToken)

		api.GET("/horoscope/signs", horoscopeController.Signs)

		auth := api.Group("/")
		auth.Use(middleware.AstroAuthMiddleware())
		{

			auth.POST("/profile/basic", profileController.SaveBasicProfile)

			auth.GET("/master/languages", profileController.GetMasterLanguages)

			auth.POST("/profile/languages", profileController.SaveLanguages)

			auth.GET("/master/skills", profileController.GetMasterSkills)

			auth.POST("/profile/skills", profileController.SaveSkills)

			auth.POST("/profile/education", profileController.SaveEducation)

			auth.POST("/profile/upload-profile-image", profileController.UploadProfileImage)

			auth.POST("/profile/professional", profileController.SaveProfessional)

			auth.POST("/profile/experience", profileController.SaveExperience)

			auth.POST("/profile/bank", profileController.SaveBankAccount)

			auth.GET("/master/document-types", profileController.GetMasterDocumentTypes)

			auth.POST("/profile/document", profileController.UploadDocument)

			auth.GET("/master/device-types", profileController.GetDeviceTypes)

			auth.GET("/master/working-hours", profileController.GetWorkingHours)

			auth.POST("/profile/availability", profileController.SaveAvailability)

			auth.GET("/profile/availability", profileController.GetAvailability)

			auth.POST("/profile/submit", profileController.SubmitProfile)

			auth.GET("/profile/progress", profileController.GetProfileProgress)

			auth.POST("/change-status", profileController.ChangeStatus)

			auth.DELETE("/delete-account", profileController.DeleteAccount)

			auth.GET("/profile", authController.GetLoggedInProfile)

			auth.PUT("/profile/update", profileController.UpdateProfile)

			auth.PUT("/profile/update-image", profileController.UpdateProfileImage)

			auth.DELETE("/profile/delete-image", profileController.DeleteProfileImage)

			auth.PUT("/update-availability", profileController.UpdateAvailability)

			auth.PUT("/bank-account", profileController.UpdateBankAccount)

			auth.PUT("/update-skills", profileController.UpdateSkills)

			auth.PUT("/update-languages", profileController.UpdateLanguages)

			auth.PUT("/update-education", profileController.UpdateEducation)

			auth.PUT("/update-professional", profileController.UpdateProfessional)

			auth.PUT("/update-experience", profileController.UpdateExperience)

			auth.PUT("/update/document", profileController.UpdateDocument)

			auth.POST("/device-token", authController.UpdateDeviceToken)

			auth.POST("/logout", authController.Logout)

			// Dashboard APIs

			auth.GET("/dashboard", dashboardController.GetDashboard)

			auth.GET("/dashboard/statistics", dashboardController.GetDashboardStatistics)

			auth.PUT("/dashboard/online-status", dashboardController.UpdateOnlineStatus)

			auth.PUT("/dashboard/chat-status", dashboardController.UpdateChatStatus)

			auth.PUT("/dashboard/call-status", dashboardController.UpdateCallStatus)

			auth.PUT("/dashboard/busy-status", dashboardController.UpdateBusyStatus)

			auth.PUT("/dashboard/quick-dnd", dashboardController.UpdateQuickDND)

			auth.POST("/dashboard/rest-time/start", dashboardController.StartRestTime)

			auth.POST("/dashboard/rest-time/end", dashboardController.EndRestTime)

			auth.PUT("/dashboard/offer", dashboardController.UpdateOffer)

			// Wallet APIs

			auth.GET("/wallet", walletController.GetWallet)

			auth.GET("/wallet/transactions", walletController.GetTransactions)

			auth.GET("/wallet/transaction/:id", walletController.GetTransactionByID)

			auth.GET("/wallet/withdraw/config", walletController.GetWithdrawConfig)

			auth.POST("/wallet/withdraw/preview", walletController.PreviewWithdraw)

			auth.POST("/wallet/withdraw", walletController.Withdraw)

			auth.GET("/wallet/withdraw-history", walletController.GetWithdrawHistory)

			auth.GET("/wallet/settlement-history", walletController.GetSettlementHistory)

			auth.GET("/settlement/upcoming", settlementController.GetUpcomingSettlement)

			auth.GET("/settlement/consultations", settlementController.GetConsultationEarnings)

			auth.GET("/settlement/history", settlementController.GetSettlementHistory)

			auth.GET("/settlement/history/:id", settlementController.GetSettlementDetail)

			auth.GET("/consultation/requests", consultationController.ListIncomingRequests)

			auth.POST("/consultation/accept", consultationController.AcceptConsultation)
			auth.POST("/consultation/reject", consultationController.RejectConsultation)

			auth.GET("/consultation/active", consultationController.GetActiveConsultation)

			auth.POST("/consultation/agora-token", consultationController.GetAgoraToken)

			auth.POST("/consultation/end", consultationController.EndConsultation)

			auth.POST("/consultation/messages/sync", consultationMessageController.SyncMessages)
			auth.GET("/consultation/messages", consultationMessageController.GetMessages)

			//Astrologer Orders Activity APIs
			// Wating List APIs
			auth.POST("/activity/waitlist/add", activityController.AddWaiting)
			auth.GET("/activity/waitlist", activityController.GetWaitingList)
			auth.DELETE("/activity/waitlist/:id", activityController.RemoveWaiting)

			// chat history APIs
			auth.GET("/activity/chat/history", activityController.GetChatHistory)
			auth.GET("/activity/chat/history/:id", activityController.GetChatDetail)

			// call history APIs
			auth.GET("/activity/call/history", activityController.GetCallHistory)
			auth.GET("/activity/call/history/:id", activityController.GetCallDetail)

			// Astro Store APIs
			auth.GET("/activity/astromall/orders", activityController.GetAstromallOrders)
			auth.GET("/activity/astromall/orders/:id", activityController.GetAstromallOrderDetail)

			//------------------------------------------------
			// Notifications
			//------------------------------------------------

			auth.GET("/notifications", notificationController.List)

			auth.GET("/notifications/count", notificationController.Count)

			auth.POST("/notifications/seen", notificationController.Seen)

			auth.POST("/notifications/read", notificationController.Read)

			auth.POST("/notifications/delete", notificationController.Delete)

			auth.DELETE("/notifications/:id", notificationController.DeleteOne)

			auth.POST("/notifications/clear", notificationController.Clear)

			//------------------------------------------------
			// Horoscope
			//------------------------------------------------

			auth.POST("/horoscope/daily", track("horoscope.daily"), horoscopeController.Daily)

			auth.POST("/horoscope/daily-moon", track("horoscope.daily_moon"), horoscopeController.DailyMoon)

			auth.POST("/horoscope/daily-nakshatra", track("horoscope.daily_nakshatra"), horoscopeController.DailyNakshatra)

			auth.POST("/horoscope/weekly", track("horoscope.weekly"), horoscopeController.Weekly)

			auth.POST("/horoscope/yearly", track("horoscope.yearly"), horoscopeController.Yearly)

			//------------------------------------------------
			// Astrology services (usage-tracked, never charged)
			//------------------------------------------------

			auth.POST("/kundali/generate", track("kundali.generate"), kundaliController.AddKundali)

			auth.GET("/kundali/chart-image", track("kundali.chart_image"), kundaliController.ChartImage)

			auth.GET("/kundali/show/:id", track("kundali.show"), kundaliController.ShowKundali)

			auth.POST("/matching/aggregate", track("matching.aggregate"), matchingController.Aggregate)

			auth.POST("/matching/ashtakoot", track("matching.ashtakoot"), matchingController.Ashtakoot)

			auth.POST("/matching/dashakoot", track("matching.dashakoot"), matchingController.Dashakoot)

			auth.POST("/matching/papasamaya", track("matching.papasamaya"), matchingController.Papasamaya)

			auth.POST("/matching/rajju-vedha", track("matching.rajju_vedha"), matchingController.RajjuVedha)

			auth.POST("/matching/nakshatra", track("matching.nakshatra"), matchingController.Nakshatra)

			auth.POST("/matching/western", track("matching.western"), matchingController.Western)

			auth.POST("/panchang/today", track("panchang.today"), panchangController.Today)

			auth.POST("/panchang/monthly", track("panchang.monthly"), panchangController.Monthly)

			auth.POST("/panchang/choghadiya", track("panchang.choghadiya"), panchangController.Choghadiya)

			auth.POST("/panchang/hora", track("panchang.hora"), panchangController.Hora)

			auth.POST("/panchang/festivals", track("panchang.festivals"), panchangController.Festivals)

			auth.POST("/panchang/sun-moon", track("panchang.sun_moon"), panchangController.SunMoon)

			auth.POST("/numerology/report", track("numerology.report"), numerologyController.Report)

			auth.POST("/numerology/day-number", track("numerology.day_number"), numerologyController.DayNumber)

			auth.POST("/numerology/table", track("numerology.table"), numerologyController.Table)

			auth.POST("/numerology/radical-number", track("numerology.radical_number"), numerologyController.RadicalNumber)

			auth.GET("/tarot/cards", track("tarot.cards"), tarotController.Cards)

			auth.GET("/tarot/cards/:id", track("tarot.cards"), tarotController.Card)

			auth.GET("/tarot/shuffle", track("tarot.shuffle"), tarotController.Shuffle)

			auth.POST("/tarot/one-card", track("tarot.one_card"), tarotController.OneCard)

			auth.POST("/tarot/three-card", track("tarot.three_card"), tarotController.ThreeCard)

			auth.POST("/tarot/love", track("tarot.love"), tarotController.Love)

			auth.POST("/tarot/love-triangle", track("tarot.love_triangle"), tarotController.LoveTriangle)

			auth.POST("/tarot/yes-no", track("tarot.yes_no"), tarotController.YesNo)

			auth.POST("/tarot/career", track("tarot.career"), tarotController.Career)

			auth.POST("/tarot/breakup", track("tarot.breakup"), tarotController.Breakup)

			auth.GET("/tarot/fortune-cookie", track("tarot.fortune_cookie"), tarotController.FortuneCookie)

		}

	}

}
