package bootstrap

import (
	accountSvc "github.com/break/junhong_cmp_fiber/internal/service/account"
	accountAuditSvc "github.com/break/junhong_cmp_fiber/internal/service/account_audit"
	assetAllocationRecordSvc "github.com/break/junhong_cmp_fiber/internal/service/asset_allocation_record"
	authSvc "github.com/break/junhong_cmp_fiber/internal/service/auth"
	carrierSvc "github.com/break/junhong_cmp_fiber/internal/service/carrier"
	commissionCalculationSvc "github.com/break/junhong_cmp_fiber/internal/service/commission_calculation"
	commissionStatsSvc "github.com/break/junhong_cmp_fiber/internal/service/commission_stats"
	commissionWithdrawalSvc "github.com/break/junhong_cmp_fiber/internal/service/commission_withdrawal"
	commissionWithdrawalSettingSvc "github.com/break/junhong_cmp_fiber/internal/service/commission_withdrawal_setting"

	deviceSvc "github.com/break/junhong_cmp_fiber/internal/service/device"
	deviceImportSvc "github.com/break/junhong_cmp_fiber/internal/service/device_import"
	enterpriseSvc "github.com/break/junhong_cmp_fiber/internal/service/enterprise"
	enterpriseCardSvc "github.com/break/junhong_cmp_fiber/internal/service/enterprise_card"
	enterpriseDeviceSvc "github.com/break/junhong_cmp_fiber/internal/service/enterprise_device"
	iotCardSvc "github.com/break/junhong_cmp_fiber/internal/service/iot_card"
	iotCardImportSvc "github.com/break/junhong_cmp_fiber/internal/service/iot_card_import"
	myCommissionSvc "github.com/break/junhong_cmp_fiber/internal/service/my_commission"
	orderSvc "github.com/break/junhong_cmp_fiber/internal/service/order"
	packageSvc "github.com/break/junhong_cmp_fiber/internal/service/package"
	packageSeriesSvc "github.com/break/junhong_cmp_fiber/internal/service/package_series"
	permissionSvc "github.com/break/junhong_cmp_fiber/internal/service/permission"
	personalCustomerSvc "github.com/break/junhong_cmp_fiber/internal/service/personal_customer"
	purchaseValidationSvc "github.com/break/junhong_cmp_fiber/internal/service/purchase_validation"
	rechargeSvc "github.com/break/junhong_cmp_fiber/internal/service/recharge"
	roleSvc "github.com/break/junhong_cmp_fiber/internal/service/role"
	shopSvc "github.com/break/junhong_cmp_fiber/internal/service/shop"

	shopCommissionSvc "github.com/break/junhong_cmp_fiber/internal/service/shop_commission"
	shopPackageAllocationSvc "github.com/break/junhong_cmp_fiber/internal/service/shop_package_allocation"
	shopPackageBatchAllocationSvc "github.com/break/junhong_cmp_fiber/internal/service/shop_package_batch_allocation"
	shopPackageBatchPricingSvc "github.com/break/junhong_cmp_fiber/internal/service/shop_package_batch_pricing"
	shopSeriesAllocationSvc "github.com/break/junhong_cmp_fiber/internal/service/shop_series_allocation"
)

type services struct {
	Account                     *accountSvc.Service
	AccountAudit                *accountAuditSvc.Service
	Role                        *roleSvc.Service
	Permission                  *permissionSvc.Service
	PersonalCustomer            *personalCustomerSvc.Service
	Shop                        *shopSvc.Service
	Auth                        *authSvc.Service
	ShopCommission              *shopCommissionSvc.Service
	CommissionWithdrawal        *commissionWithdrawalSvc.Service
	CommissionWithdrawalSetting *commissionWithdrawalSettingSvc.Service
	CommissionCalculation       *commissionCalculationSvc.Service
	Enterprise                  *enterpriseSvc.Service
	EnterpriseCard              *enterpriseCardSvc.Service
	EnterpriseDevice            *enterpriseDeviceSvc.Service
	Authorization               *enterpriseCardSvc.AuthorizationService
	MyCommission                *myCommissionSvc.Service
	IotCard                     *iotCardSvc.Service
	IotCardImport               *iotCardImportSvc.Service
	Device                      *deviceSvc.Service
	DeviceImport                *deviceImportSvc.Service
	AssetAllocationRecord       *assetAllocationRecordSvc.Service
	Carrier                     *carrierSvc.Service
	PackageSeries               *packageSeriesSvc.Service
	Package                     *packageSvc.Service
	ShopSeriesAllocation        *shopSeriesAllocationSvc.Service
	ShopPackageAllocation       *shopPackageAllocationSvc.Service
	ShopPackageBatchAllocation  *shopPackageBatchAllocationSvc.Service
	ShopPackageBatchPricing     *shopPackageBatchPricingSvc.Service
	CommissionStats             *commissionStatsSvc.Service
	PurchaseValidation          *purchaseValidationSvc.Service
	Order                       *orderSvc.Service
	Recharge                    *rechargeSvc.Service
}

func initServices(s *stores, deps *Dependencies) *services {
	purchaseValidation := purchaseValidationSvc.New(deps.DB, s.IotCard, s.Device, s.Package, s.ShopSeriesAllocation)
	accountAudit := accountAuditSvc.NewService(s.AccountOperationLog)

	return &services{
		Account:                     accountSvc.New(s.Account, s.Role, s.AccountRole, s.Shop, s.Enterprise, accountAudit),
		AccountAudit:                accountAudit,
		Role:                        roleSvc.New(s.Role, s.Permission, s.RolePermission),
		Permission:                  permissionSvc.New(s.Permission, s.AccountRole, s.RolePermission, deps.Redis),
		PersonalCustomer:            personalCustomerSvc.NewService(s.PersonalCustomer, s.PersonalCustomerPhone, deps.VerificationService, deps.JWTManager, deps.WechatOfficialAccount, deps.Logger),
		Shop:                        shopSvc.New(s.Shop, s.Account),
		Auth:                        authSvc.New(s.Account, s.AccountRole, s.RolePermission, s.Permission, deps.TokenManager, deps.Logger),
		ShopCommission:              shopCommissionSvc.New(s.Shop, s.Account, s.Wallet, s.CommissionWithdrawalRequest, s.CommissionRecord),
		CommissionWithdrawal:        commissionWithdrawalSvc.New(deps.DB, s.Shop, s.Account, s.Wallet, s.WalletTransaction, s.CommissionWithdrawalRequest),
		CommissionWithdrawalSetting: commissionWithdrawalSettingSvc.New(deps.DB, s.Account, s.CommissionWithdrawalSetting),
		CommissionCalculation: commissionCalculationSvc.New(
			deps.DB,
			s.CommissionRecord,
			s.Shop,
			s.ShopSeriesAllocation,
			s.ShopSeriesOneTimeCommissionTier,
			s.IotCard,
			s.Device,
			s.Wallet,
			s.WalletTransaction,
			s.Order,
			s.OrderItem,
			s.Package,
			commissionStatsSvc.New(s.ShopSeriesCommissionStats),
			deps.Logger,
		),
		Enterprise:                 enterpriseSvc.New(deps.DB, s.Enterprise, s.Shop, s.Account),
		EnterpriseCard:             enterpriseCardSvc.New(deps.DB, s.Enterprise, s.EnterpriseCardAuthorization),
		EnterpriseDevice:           enterpriseDeviceSvc.New(deps.DB, s.Enterprise, s.Device, s.DeviceSimBinding, s.EnterpriseDeviceAuthorization, s.EnterpriseCardAuthorization, deps.Logger),
		Authorization:              enterpriseCardSvc.NewAuthorizationService(s.Enterprise, s.IotCard, s.EnterpriseCardAuthorization, deps.Logger),
		MyCommission:               myCommissionSvc.New(deps.DB, s.Shop, s.Wallet, s.CommissionWithdrawalRequest, s.CommissionWithdrawalSetting, s.CommissionRecord, s.WalletTransaction),
		IotCard:                    iotCardSvc.New(deps.DB, s.IotCard, s.Shop, s.AssetAllocationRecord, s.ShopSeriesAllocation, s.PackageSeries, deps.GatewayClient, deps.Logger),
		IotCardImport:              iotCardImportSvc.New(deps.DB, s.IotCardImportTask, deps.QueueClient),
		Device:                     deviceSvc.New(deps.DB, s.Device, s.DeviceSimBinding, s.IotCard, s.Shop, s.AssetAllocationRecord, s.ShopSeriesAllocation, s.PackageSeries),
		DeviceImport:               deviceImportSvc.New(deps.DB, s.DeviceImportTask, deps.QueueClient),
		AssetAllocationRecord:      assetAllocationRecordSvc.New(deps.DB, s.AssetAllocationRecord, s.Shop, s.Account),
		Carrier:                    carrierSvc.New(s.Carrier),
		PackageSeries:              packageSeriesSvc.New(s.PackageSeries),
		Package:                    packageSvc.New(s.Package, s.PackageSeries, s.ShopPackageAllocation, s.ShopSeriesAllocation),
		ShopSeriesAllocation:       shopSeriesAllocationSvc.New(s.ShopSeriesAllocation, s.ShopSeriesAllocationConfig, s.ShopSeriesOneTimeCommissionTier, s.Shop, s.PackageSeries, s.Package),
		ShopPackageAllocation:      shopPackageAllocationSvc.New(s.ShopPackageAllocation, s.ShopSeriesAllocation, s.ShopPackageAllocationPriceHistory, s.Shop, s.Package),
		ShopPackageBatchAllocation: shopPackageBatchAllocationSvc.New(deps.DB, s.Package, s.ShopSeriesAllocation, s.ShopPackageAllocation, s.ShopSeriesAllocationConfig, s.ShopSeriesCommissionStats, s.Shop),
		ShopPackageBatchPricing:    shopPackageBatchPricingSvc.New(deps.DB, s.ShopPackageAllocation, s.ShopPackageAllocationPriceHistory, s.Shop),
		CommissionStats:            commissionStatsSvc.New(s.ShopSeriesCommissionStats),
		PurchaseValidation:         purchaseValidation,
		Order:                      orderSvc.New(deps.DB, s.Order, s.OrderItem, s.Wallet, purchaseValidation, s.ShopSeriesAllocationConfig, s.ShopSeriesAllocation, s.IotCard, s.Device, deps.WechatPayment, deps.QueueClient, deps.Logger),
		Recharge:                   rechargeSvc.New(deps.DB, s.Recharge, s.Wallet, s.WalletTransaction, s.IotCard, s.Device, s.ShopSeriesAllocation, s.CommissionRecord, deps.Logger),
	}
}
