package user_routes

import (
	configs "astrology-api/configs"
	usercontroller "astrology-api/controllers/user"
	middleware "astrology-api/middleware"
	"astrology-api/notifications"

	"astrology-api/repositories"
	"astrology-api/services"

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

func RegisterUserRoutes(router *gin.RouterGroup) {

	kundaliController := usercontroller.NewKundaliController()

	tarotController := usercontroller.NewTarotController(services.NewTarotService())

	storeController := usercontroller.NewStoreController()

	storeProductController := usercontroller.NewStoreProductController()

	orderAddressController := usercontroller.NewOrderAddressController()

	reportController := usercontroller.NewReportController()

	walletRepository := repositories.NewWalletRepository(configs.DB)

	walletService := services.NewWalletService(walletRepository, nil)

	walletController := usercontroller.NewWalletController(walletService)

	consultationRepository := repositories.NewConsultationRepository(configs.DB)

	agoraTokenService := services.NewAgoraTokenService(configs.Agora)

	consultationService := services.NewConsultationService(consultationRepository, agoraTokenService)

	consultationController := usercontroller.NewConsultationController(consultationService)

	consultationMessageController := usercontroller.NewConsultationMessageController(
		services.NewConsultationMessageService(consultationRepository),
	)

	matchingController := usercontroller.NewMatchingController(services.NewMatchingService())

	horoscopeController := usercontroller.NewHoroscopeController(services.NewHoroscopeService())

	panchangController := usercontroller.NewPanchangController(services.NewPanchangService())

	numerologyController := usercontroller.NewNumerologyController(services.NewNumerologyService())

	astrologerController := usercontroller.NewAstrologerController()

	followerController := usercontroller.NewFollowerController()

	userReviewController := usercontroller.NewUserReviewController()

	notificationController := usercontroller.NewNotificationController(
		notifications.NewCenter(configs.DB),
	)

	track := middleware.TrackAstrologyService(middleware.CustomerSide)

	api := router.Group("/user")
	{

		api.POST("/register", usercontroller.Register)

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

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

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

		api.POST("/social/mobile-login", usercontroller.MobileSocialLogin)

		api.POST("/social/web-login", usercontroller.WebSocialLogin)

		api.POST("/social/send-mobile-otp", usercontroller.SendSocialMobileOTP)

		api.POST("/social/verify-mobile-otp", usercontroller.VerifySocialMobileOTP)

		api.POST("/social/facebook-login", usercontroller.FacebookSocialLogin)

		api.POST("/social/send-email-otp", usercontroller.SendSocialEmailOTP)

		api.POST("/social/verify-email-otp", usercontroller.VerifySocialEmailOTP)

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

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

		api.POST("/forgot-password", usercontroller.ForgotPassword)

		api.POST("/reset-password", usercontroller.ResetPassword)

		// Home
		api.GET("/get-user-home", usercontroller.GetUserHome)

		// Public: website home page "expert astrologers, ready now" block.
		api.GET("/astrologers/top", astrologerController.GetTopAstrologers)

		// Public so the sign picker can render before login.
		api.GET("/horoscope/signs", horoscopeController.Signs)

		api.POST("/getSystemFlag", usercontroller.GetSystemFlag)

		api.POST("/getSubCategory", usercontroller.GetSubCategory)

		api.POST("/getAppLanguage", usercontroller.GetAppLanguage)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

			auth.GET("/profile", usercontroller.Profile)

			auth.POST("/profile/upload", usercontroller.UploadProfileImage)

			auth.DELETE("/profile/remove-image", usercontroller.RemoveProfileImage)

			auth.PUT("/update-profile", usercontroller.UpdateProfile)

			auth.POST("/update-status", usercontroller.UpdateUserStatus)

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

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

			auth.POST("/delete", usercontroller.DeleteUser)

			auth.POST("/refresh-token", usercontroller.RefreshToken)

			auth.POST("/order-address/add", orderAddressController.AddOrderAddress)

			auth.PUT("/order-address/update/:id", orderAddressController.UpdateOrderAddress)

			auth.POST("/order-address/list", orderAddressController.GetOrderAddresses)

			auth.GET("/consultation/precheck", consultationController.Precheck)

			auth.POST("/consultation/start", consultationController.StartConsultation)

			auth.GET("/consultation/status", consultationController.GetConsultationStatus)

			auth.POST("/consultation/cancel", consultationController.CancelConsultation)

			// Waiting queue: join a busy astrologer's queue, poll for the
			// turn, connect when notified, or leave.
			auth.POST("/consultation/queue/join", consultationController.JoinQueue)
			auth.GET("/consultation/queue/status", consultationController.GetQueueStatus)
			auth.POST("/consultation/queue/connect", consultationController.ConnectQueue)
			auth.POST("/consultation/queue/cancel", consultationController.CancelQueue)

			auth.POST("/consultation/start-chat", consultationController.StartChat)

			auth.POST("/consultation/tick", consultationController.Tick)

			auth.POST("/consultation/continue-paid", consultationController.ContinuePaid)

			auth.POST("/consultation/extend", consultationController.ExtendConsultation)

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

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

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

			auth.POST("/consultation/history", consultationController.GetHistory)

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

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

			auth.POST("/report/chat-history", reportController.GetChatHistory)

			auth.POST("/report/call-history", reportController.GetCallHistory)

			auth.POST("/astrologers/list", astrologerController.GetAstrologers)

			auth.POST("/astrologers/search", astrologerController.SearchAstrologers)

			auth.POST("/astrologers/getAstrologerById", astrologerController.GetAstrologerByID)

			auth.GET("/wallet/offers", walletController.GetRechargeOffers)

			auth.POST("/wallet/create-order", walletController.CreatePayment)

			auth.POST("/wallet/verify-payment", walletController.VerifyPayment)

			// User Follower APIs

			auth.POST("/follower/add", followerController.AddFollowing)

			auth.POST("/follower/update", followerController.UpdateFollowing)

			auth.POST("/getFollower", followerController.GetFollowing)

			auth.POST("/getAstrologerFollower", followerController.GetAstrologerFollower)

			// User Rerview APIs

			auth.POST("/userReview/add", userReviewController.AddReview)

			auth.PUT("/userReview/update/:id", userReviewController.UpdateReview)

			auth.DELETE("/userReview/delete/:id", userReviewController.DeleteReview)

			auth.POST("/getAstrologerUserReview", userReviewController.GetAstrologerUserReview)

			auth.POST("/getUserHistoryReview", userReviewController.GetUserReviewHistory)

			auth.POST("/userReview/reply", userReviewController.ReplyReview)

			auth.POST("/blockUserReview", userReviewController.BlockReview)

			auth.POST("/getBlockUserReview", userReviewController.GetBlockedReviews)

			auth.POST("/getUserReviewForAdmin", userReviewController.GetUserReviewForAdmin)

			auth.POST("/getAverageRating", userReviewController.GetAverageRating)

			// Generate Kundali Report From Vedic Api
			auth.POST("/kundali/add", track("kundali.add"), kundaliController.AddKundali)

			// Users Saved Kundali Operation

			auth.POST("/kundali/list", track("kundali.list"), kundaliController.GetKundalis)

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

			auth.PUT("/kundali/update/:id", track("kundali.update"), kundaliController.UpdateKundali)

			auth.POST("/kundali/update/:id", track("kundali.update"), kundaliController.UpdateKundali)

			auth.DELETE("/kundali/delete", track("kundali.delete"), kundaliController.DeleteKundali)

			auth.GET("/kundali/download/:id", track("kundali.download"), kundaliController.DownloadKundali)

			// Kundali Matching
			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("/matching/add", track("matching.save"), matchingController.Save)

			auth.POST("/matching/list", track("matching.list"), matchingController.List)

			auth.GET("/matching/show/:id", track("matching.show"), matchingController.Show)

			auth.DELETE("/matching/delete/:id", matchingController.Delete)

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

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

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

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

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

			auth.POST("/horoscope/feedback", horoscopeController.Feedback)

			// Panchang
			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)

			// Numerology
			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)

			// Wallet
			auth.POST("/wallet/transactions", walletController.GetWalletTransactions)

			auth.POST("/wallet/transaction/details", walletController.GetWalletTransactionDetail)

			auth.GET("/wallet/summary", walletController.GetWalletSummary)

			// Astro Stoire
			auth.POST("/store/home", storeController.StoreHome)

			// Product APIs

			auth.POST("/store/products", storeProductController.GetProducts)

			auth.POST("/store/product/details", storeProductController.GetProductDetail)

			auth.POST("/store/search", storeProductController.SearchProducts)

			auth.POST("/store/similar-products", storeProductController.GetSimilarProducts)

			auth.POST("/store/product/reviews", storeProductController.GetProductReviews)

			auth.POST("/store/product/faqs", storeProductController.GetProductFAQs)

			//------------------------------------------------
			// 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)

		}
	}
}
