package svc

import (
	"qnc-server/app/main/api/internal/config"
	"qnc-server/app/main/api/internal/middleware"
	"qnc-server/app/main/api/internal/service"
	"qnc-server/app/main/model"
	"qnc-server/pkg/core/aliyun/cloudauth"

	"github.com/hibiken/asynq"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/redis"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"github.com/zeromicro/go-zero/rest"
)

// ServiceContext 服务上下文
type ServiceContext struct {
	Config config.Config
	Redis  *redis.Redis

	// 中间件
	AuthInterceptor     rest.Middleware
	UserAuthInterceptor rest.Middleware
	// 用户相关模型
	UserModel     model.UserModel
	UserAuthModel model.UserAuthModel
	UserTempModel model.UserTempModel

	// 产品相关模型
	ProductModel        model.ProductModel
	FeatureModel        model.FeatureModel
	ProductFeatureModel model.ProductFeatureModel

	// 订单相关模型
	OrderModel              model.OrderModel
	OrderRefundModel        model.OrderRefundModel
	AuthorizationModel      model.AuthorizationModel
	AuthorizationFaceModel  model.AuthorizationFaceModel
	QueryModel              model.QueryModel
	QueryCleanupLogModel    model.QueryCleanupLogModel
	QueryCleanupDetailModel model.QueryCleanupDetailModel
	QueryCleanupConfigModel model.QueryCleanupConfigModel

	// 代理相关模型
	AgentModel                        model.AgentModel
	AgentAuditModel                   model.AgentAuditModel
	AgentClosureModel                 model.AgentClosureModel
	AgentCommissionModel              model.AgentCommissionModel
	AgentCommissionDeductionModel     model.AgentCommissionDeductionModel
	AgentWalletModel                  model.AgentWalletModel
	AgentLinkModel                    model.AgentLinkModel
	AgentOrderModel                   model.AgentOrderModel
	AgentRewardsModel                 model.AgentRewardsModel
	AgentMembershipConfigModel        model.AgentMembershipConfigModel
	AgentMembershipRechargeOrderModel model.AgentMembershipRechargeOrderModel
	AgentMembershipUserConfigModel    model.AgentMembershipUserConfigModel
	AgentProductConfigModel           model.AgentProductConfigModel
	AgentPlatformDeductionModel       model.AgentPlatformDeductionModel
	AgentActiveStatModel              model.AgentActiveStatModel
	AgentWithdrawalModel              model.AgentWithdrawalModel
	AgentRealNameModel                model.AgentRealNameModel

	// 管理后台相关模型
	AdminApiModel                       model.AdminApiModel
	AdminMenuModel                      model.AdminMenuModel
	AdminRoleModel                      model.AdminRoleModel
	AdminRoleApiModel                   model.AdminRoleApiModel
	AdminRoleMenuModel                  model.AdminRoleMenuModel
	AdminUserModel                      model.AdminUserModel
	AdminUserRoleModel                  model.AdminUserRoleModel
	AdminDictDataModel                  model.AdminDictDataModel
	AdminDictTypeModel                  model.AdminDictTypeModel
	AdminPromotionLinkModel             model.AdminPromotionLinkModel
	AdminPromotionLinkStatsTotalModel   model.AdminPromotionLinkStatsTotalModel
	AdminPromotionLinkStatsHistoryModel model.AdminPromotionLinkStatsHistoryModel
	AdminPromotionOrderModel            model.AdminPromotionOrderModel

	// 其他模型
	ExampleModel             model.ExampleModel
	GlobalNotificationsModel model.GlobalNotificationsModel

	// 服务
	AlipayService                  *service.AliPayService
	WechatPayService               *service.WechatPayService
	ApplePayService                *service.ApplePayService
	WestDexService                 *service.WestDexService
	YushanService                  *service.YushanService
	ApiRequestService              *service.ApiRequestService
	AsynqServer                    *asynq.Server
	AsynqService                   *service.AsynqService
	VerificationService            *service.VerificationService
	AgentService                   *service.AgentService
	UserService                    *service.UserService
	DictService                    *service.DictService
	AdminPromotionLinkStatsService *service.AdminPromotionLinkStatsService
	ImageService                   *service.ImageService

	// core service
	CloudAuthService *cloudauth.CloudAuthClient
}

// 用户相关模型初始化
type userModels struct {
	UserModel     model.UserModel
	UserAuthModel model.UserAuthModel
	UserTempModel model.UserTempModel
}

func initUserModels(db sqlx.SqlConn, redis cache.CacheConf) userModels {
	return userModels{
		UserModel:     model.NewUserModel(db, redis),
		UserAuthModel: model.NewUserAuthModel(db, redis),
		UserTempModel: model.NewUserTempModel(db, redis),
	}
}

// 产品相关模型初始化
type productModels struct {
	ProductModel        model.ProductModel
	FeatureModel        model.FeatureModel
	ProductFeatureModel model.ProductFeatureModel
}

func initProductModels(db sqlx.SqlConn, redis cache.CacheConf) productModels {
	return productModels{
		ProductModel:        model.NewProductModel(db, redis),
		FeatureModel:        model.NewFeatureModel(db, redis),
		ProductFeatureModel: model.NewProductFeatureModel(db, redis),
	}
}

// 订单相关模型初始化
type orderModels struct {
	OrderModel              model.OrderModel
	OrderRefundModel        model.OrderRefundModel
	AuthorizationModel      model.AuthorizationModel
	AuthorizationFaceModel  model.AuthorizationFaceModel
	QueryModel              model.QueryModel
	QueryCleanupLogModel    model.QueryCleanupLogModel
	QueryCleanupDetailModel model.QueryCleanupDetailModel
	QueryCleanupConfigModel model.QueryCleanupConfigModel
}

func initOrderModels(db sqlx.SqlConn, redis cache.CacheConf) orderModels {
	return orderModels{
		OrderModel:              model.NewOrderModel(db, redis),
		OrderRefundModel:        model.NewOrderRefundModel(db, redis),
		AuthorizationModel:      model.NewAuthorizationModel(db, redis),
		AuthorizationFaceModel:  model.NewAuthorizationFaceModel(db, redis),
		QueryModel:              model.NewQueryModel(db, redis),
		QueryCleanupLogModel:    model.NewQueryCleanupLogModel(db, redis),
		QueryCleanupDetailModel: model.NewQueryCleanupDetailModel(db, redis),
		QueryCleanupConfigModel: model.NewQueryCleanupConfigModel(db, redis),
	}
}

// 代理相关模型初始化
type agentModels struct {
	AgentModel                        model.AgentModel
	AgentAuditModel                   model.AgentAuditModel
	AgentClosureModel                 model.AgentClosureModel
	AgentCommissionModel              model.AgentCommissionModel
	AgentCommissionDeductionModel     model.AgentCommissionDeductionModel
	AgentWalletModel                  model.AgentWalletModel
	AgentLinkModel                    model.AgentLinkModel
	AgentOrderModel                   model.AgentOrderModel
	AgentRewardsModel                 model.AgentRewardsModel
	AgentMembershipConfigModel        model.AgentMembershipConfigModel
	AgentMembershipRechargeOrderModel model.AgentMembershipRechargeOrderModel
	AgentMembershipUserConfigModel    model.AgentMembershipUserConfigModel
	AgentProductConfigModel           model.AgentProductConfigModel
	AgentPlatformDeductionModel       model.AgentPlatformDeductionModel
	AgentActiveStatModel              model.AgentActiveStatModel
	AgentWithdrawalModel              model.AgentWithdrawalModel
	AgentRealNameModel                model.AgentRealNameModel
}

func initAgentModels(db sqlx.SqlConn, redis cache.CacheConf) agentModels {
	return agentModels{
		AgentModel:                        model.NewAgentModel(db, redis),
		AgentAuditModel:                   model.NewAgentAuditModel(db, redis),
		AgentClosureModel:                 model.NewAgentClosureModel(db, redis),
		AgentCommissionModel:              model.NewAgentCommissionModel(db, redis),
		AgentCommissionDeductionModel:     model.NewAgentCommissionDeductionModel(db, redis),
		AgentWalletModel:                  model.NewAgentWalletModel(db, redis),
		AgentLinkModel:                    model.NewAgentLinkModel(db, redis),
		AgentOrderModel:                   model.NewAgentOrderModel(db, redis),
		AgentRewardsModel:                 model.NewAgentRewardsModel(db, redis),
		AgentMembershipConfigModel:        model.NewAgentMembershipConfigModel(db, redis),
		AgentMembershipRechargeOrderModel: model.NewAgentMembershipRechargeOrderModel(db, redis),
		AgentMembershipUserConfigModel:    model.NewAgentMembershipUserConfigModel(db, redis),
		AgentProductConfigModel:           model.NewAgentProductConfigModel(db, redis),
		AgentPlatformDeductionModel:       model.NewAgentPlatformDeductionModel(db, redis),
		AgentActiveStatModel:              model.NewAgentActiveStatModel(db, redis),
		AgentWithdrawalModel:              model.NewAgentWithdrawalModel(db, redis),
		AgentRealNameModel:                model.NewAgentRealNameModel(db, redis),
	}
}

// 管理后台相关模型初始化
type adminModels struct {
	AdminApiModel                       model.AdminApiModel
	AdminMenuModel                      model.AdminMenuModel
	AdminRoleModel                      model.AdminRoleModel
	AdminRoleApiModel                   model.AdminRoleApiModel
	AdminRoleMenuModel                  model.AdminRoleMenuModel
	AdminUserModel                      model.AdminUserModel
	AdminUserRoleModel                  model.AdminUserRoleModel
	AdminDictDataModel                  model.AdminDictDataModel
	AdminDictTypeModel                  model.AdminDictTypeModel
	AdminPromotionLinkModel             model.AdminPromotionLinkModel
	AdminPromotionLinkStatsTotalModel   model.AdminPromotionLinkStatsTotalModel
	AdminPromotionLinkStatsHistoryModel model.AdminPromotionLinkStatsHistoryModel
	AdminPromotionOrderModel            model.AdminPromotionOrderModel
}

func initAdminModels(db sqlx.SqlConn, redis cache.CacheConf) adminModels {
	return adminModels{
		AdminApiModel:                       model.NewAdminApiModel(db, redis),
		AdminMenuModel:                      model.NewAdminMenuModel(db, redis),
		AdminRoleModel:                      model.NewAdminRoleModel(db, redis),
		AdminRoleApiModel:                   model.NewAdminRoleApiModel(db, redis),
		AdminRoleMenuModel:                  model.NewAdminRoleMenuModel(db, redis),
		AdminUserModel:                      model.NewAdminUserModel(db, redis),
		AdminUserRoleModel:                  model.NewAdminUserRoleModel(db, redis),
		AdminDictDataModel:                  model.NewAdminDictDataModel(db, redis),
		AdminDictTypeModel:                  model.NewAdminDictTypeModel(db, redis),
		AdminPromotionLinkModel:             model.NewAdminPromotionLinkModel(db, redis),
		AdminPromotionLinkStatsTotalModel:   model.NewAdminPromotionLinkStatsTotalModel(db, redis),
		AdminPromotionLinkStatsHistoryModel: model.NewAdminPromotionLinkStatsHistoryModel(db, redis),
		AdminPromotionOrderModel:            model.NewAdminPromotionOrderModel(db, redis),
	}
}

// 其他模型初始化
type otherModels struct {
	ExampleModel             model.ExampleModel
	GlobalNotificationsModel model.GlobalNotificationsModel
}

func initOtherModels(db sqlx.SqlConn, redis cache.CacheConf) otherModels {
	return otherModels{
		ExampleModel:             model.NewExampleModel(db, redis),
		GlobalNotificationsModel: model.NewGlobalNotificationsModel(db, redis),
	}
}

// 服务初始化
type services struct {
	AlipayService                  *service.AliPayService
	WechatPayService               *service.WechatPayService
	ApplePayService                *service.ApplePayService
	WestDexService                 *service.WestDexService
	YushanService                  *service.YushanService
	ApiRequestService              *service.ApiRequestService
	AsynqServer                    *asynq.Server
	AsynqService                   *service.AsynqService
	VerificationService            *service.VerificationService
	AgentService                   *service.AgentService
	UserService                    *service.UserService
	DictService                    *service.DictService
	AdminPromotionLinkStatsService *service.AdminPromotionLinkStatsService
	ImageService                   *service.ImageService
	CloudAuthService               *cloudauth.CloudAuthClient
}

func initServices(c config.Config, userAuthModel model.UserAuthModel, westDexService *service.WestDexService,
	yushanService *service.YushanService, featureModel model.FeatureModel,
	productFeatureModel model.ProductFeatureModel, agentModels agentModels,
	userModels userModels, adminModels adminModels, userTempModel model.UserTempModel) services {

	alipayService := service.NewAliPayService(c)
	wechatPayService := service.NewWechatPayService(c, userAuthModel, service.InitTypeWxPayPubKey)
	applePayService := service.NewApplePayService(c)
	apiRequestService := service.NewApiRequestService(c, westDexService, yushanService, featureModel, productFeatureModel)
	verificationService := service.NewVerificationService(c, westDexService, apiRequestService)
	asynqService := service.NewAsynqService(c)
	agentService := service.NewAgentService(c, agentModels.AgentModel, agentModels.AgentAuditModel,
		agentModels.AgentClosureModel, agentModels.AgentCommissionModel,
		agentModels.AgentCommissionDeductionModel, agentModels.AgentWalletModel,
		agentModels.AgentLinkModel, agentModels.AgentOrderModel, agentModels.AgentRewardsModel,
		agentModels.AgentMembershipConfigModel, agentModels.AgentMembershipRechargeOrderModel,
		agentModels.AgentMembershipUserConfigModel, agentModels.AgentProductConfigModel,
		agentModels.AgentPlatformDeductionModel, agentModels.AgentActiveStatModel,
		asynqService, agentModels.AgentWithdrawalModel)
	userService := service.NewUserService(&c, userModels.UserModel, userModels.UserAuthModel, userTempModel, agentModels.AgentModel)
	dictService := service.NewDictService(adminModels.AdminDictTypeModel, adminModels.AdminDictDataModel)
	AdminPromotionLinkStatsService := service.NewAdminPromotionLinkStatsService(adminModels.AdminPromotionLinkModel, adminModels.AdminPromotionLinkStatsTotalModel, adminModels.AdminPromotionLinkStatsHistoryModel)
	imageService := service.NewImageService()
	asynqServer := asynq.NewServer(
		asynq.RedisClientOpt{Addr: c.CacheRedis[0].Host, Password: c.CacheRedis[0].Pass},
		asynq.Config{
			IsFailure: func(err error) bool {
				logx.Errorf("异步任务失败: %+v \n", err)
				return true
			},
			Concurrency: 10,
		},
	)

	cloudAuthService, err := cloudauth.NewCloudAuthClient(cloudauth.CloudAuthConfig{
		AccessKeyId:     c.CloudAuth.AccessKeyId,
		AccessKeySecret: c.CloudAuth.AccessKeySecret,
		Endpoint:        c.CloudAuth.Endpoint,
		SceneId:         c.CloudAuth.SceneId,
		ReturnUrl:       c.CloudAuth.ReturnUrl,
	})
	if err != nil {
		logx.Errorf("初始化阿里云人脸认证服务失败: %+v", err)
		panic(err)
	}

	return services{
		AlipayService:                  alipayService,
		WechatPayService:               wechatPayService,
		ApplePayService:                applePayService,
		WestDexService:                 westDexService,
		YushanService:                  yushanService,
		ApiRequestService:              apiRequestService,
		AsynqServer:                    asynqServer,
		AsynqService:                   asynqService,
		VerificationService:            verificationService,
		AgentService:                   agentService,
		UserService:                    userService,
		DictService:                    dictService,
		AdminPromotionLinkStatsService: AdminPromotionLinkStatsService,
		ImageService:                   imageService,
		// core service
		CloudAuthService: cloudAuthService,
	}
}

// NewServiceContext 创建服务上下文
func NewServiceContext(c config.Config) *ServiceContext {
	db := sqlx.NewMysql(c.DataSource)

	// 使用配置中的CacheRedis配置
	cacheConf := c.CacheRedis

	// 初始化Redis客户端（用于异步任务等）
	redisConf := redis.RedisConf{
		Host: cacheConf[0].Host,
		Pass: cacheConf[0].Pass,
		Type: cacheConf[0].Type,
	}
	redisClient := redis.MustNewRedis(redisConf)

	// 初始化各个模块的模型
	userModels := initUserModels(db, cacheConf)
	productModels := initProductModels(db, cacheConf)
	orderModels := initOrderModels(db, cacheConf)
	agentModels := initAgentModels(db, cacheConf)
	adminModels := initAdminModels(db, cacheConf)
	otherModels := initOtherModels(db, cacheConf)

	// 初始化第三方服务
	westDexService := service.NewWestDexService(c)
	yushanService := service.NewYushanService(c)

	// 初始化所有服务
	services := initServices(c, userModels.UserAuthModel, westDexService, yushanService,
		productModels.FeatureModel, productModels.ProductFeatureModel, agentModels, userModels, adminModels, userModels.UserTempModel)

	return &ServiceContext{
		Config:              c,
		Redis:               redisClient,
		AuthInterceptor:     middleware.NewAuthInterceptorMiddleware(c).Handle,
		UserAuthInterceptor: middleware.NewUserAuthInterceptorMiddleware().Handle,
		// 用户相关模型
		UserModel:     userModels.UserModel,
		UserAuthModel: userModels.UserAuthModel,
		UserTempModel: userModels.UserTempModel,
		// 产品相关模型
		ProductModel:        productModels.ProductModel,
		FeatureModel:        productModels.FeatureModel,
		ProductFeatureModel: productModels.ProductFeatureModel,

		// 订单相关模型
		OrderModel:              orderModels.OrderModel,
		QueryModel:              orderModels.QueryModel,
		AuthorizationModel:      orderModels.AuthorizationModel,
		AuthorizationFaceModel:  orderModels.AuthorizationFaceModel,
		OrderRefundModel:        orderModels.OrderRefundModel,
		QueryCleanupLogModel:    orderModels.QueryCleanupLogModel,
		QueryCleanupDetailModel: orderModels.QueryCleanupDetailModel,
		QueryCleanupConfigModel: orderModels.QueryCleanupConfigModel,
		// 代理相关模型
		AgentModel:                        agentModels.AgentModel,
		AgentAuditModel:                   agentModels.AgentAuditModel,
		AgentClosureModel:                 agentModels.AgentClosureModel,
		AgentCommissionModel:              agentModels.AgentCommissionModel,
		AgentCommissionDeductionModel:     agentModels.AgentCommissionDeductionModel,
		AgentWalletModel:                  agentModels.AgentWalletModel,
		AgentLinkModel:                    agentModels.AgentLinkModel,
		AgentOrderModel:                   agentModels.AgentOrderModel,
		AgentRewardsModel:                 agentModels.AgentRewardsModel,
		AgentMembershipConfigModel:        agentModels.AgentMembershipConfigModel,
		AgentMembershipRechargeOrderModel: agentModels.AgentMembershipRechargeOrderModel,
		AgentMembershipUserConfigModel:    agentModels.AgentMembershipUserConfigModel,
		AgentProductConfigModel:           agentModels.AgentProductConfigModel,
		AgentPlatformDeductionModel:       agentModels.AgentPlatformDeductionModel,
		AgentActiveStatModel:              agentModels.AgentActiveStatModel,
		AgentWithdrawalModel:              agentModels.AgentWithdrawalModel,
		AgentRealNameModel:                agentModels.AgentRealNameModel,

		// 管理后台相关模型
		AdminApiModel:                       adminModels.AdminApiModel,
		AdminMenuModel:                      adminModels.AdminMenuModel,
		AdminRoleModel:                      adminModels.AdminRoleModel,
		AdminRoleApiModel:                   adminModels.AdminRoleApiModel,
		AdminRoleMenuModel:                  adminModels.AdminRoleMenuModel,
		AdminUserModel:                      adminModels.AdminUserModel,
		AdminUserRoleModel:                  adminModels.AdminUserRoleModel,
		AdminDictDataModel:                  adminModels.AdminDictDataModel,
		AdminDictTypeModel:                  adminModels.AdminDictTypeModel,
		AdminPromotionLinkModel:             adminModels.AdminPromotionLinkModel,
		AdminPromotionLinkStatsTotalModel:   adminModels.AdminPromotionLinkStatsTotalModel,
		AdminPromotionLinkStatsHistoryModel: adminModels.AdminPromotionLinkStatsHistoryModel,
		AdminPromotionOrderModel:            adminModels.AdminPromotionOrderModel,

		// 其他模型
		ExampleModel:             otherModels.ExampleModel,
		GlobalNotificationsModel: otherModels.GlobalNotificationsModel,

		// 服务
		AlipayService:                  services.AlipayService,
		WechatPayService:               services.WechatPayService,
		ApplePayService:                services.ApplePayService,
		WestDexService:                 services.WestDexService,
		YushanService:                  services.YushanService,
		ApiRequestService:              services.ApiRequestService,
		AsynqServer:                    services.AsynqServer,
		AsynqService:                   services.AsynqService,
		VerificationService:            services.VerificationService,
		AgentService:                   services.AgentService,
		UserService:                    services.UserService,
		DictService:                    services.DictService,
		AdminPromotionLinkStatsService: services.AdminPromotionLinkStatsService,
		ImageService:                   services.ImageService,

		// core service
		CloudAuthService: services.CloudAuthService,
	}
}

func (s *ServiceContext) Close() {
	if s.AsynqService != nil {
		s.AsynqService.Close()
	}
}
