package bootstrap

import (
	cardObservationApp "github.com/break/junhong_cmp_fiber/internal/application/cardobservation"
	walletapp "github.com/break/junhong_cmp_fiber/internal/application/wallet"
	cardObservationInfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/cardobservation"
	"github.com/break/junhong_cmp_fiber/internal/infrastructure/integrationlog"
	"github.com/break/junhong_cmp_fiber/internal/infrastructure/messaging/outbox"
	walletinfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/wallet"
	assetAuditSvc "github.com/break/junhong_cmp_fiber/internal/service/asset_audit"
	"github.com/break/junhong_cmp_fiber/internal/service/commission_calculation"
	"github.com/break/junhong_cmp_fiber/internal/service/commission_stats"
	deviceSvc "github.com/break/junhong_cmp_fiber/internal/service/device"
	iotCardSvc "github.com/break/junhong_cmp_fiber/internal/service/iot_card"
	orderSvc "github.com/break/junhong_cmp_fiber/internal/service/order"
	packagepkg "github.com/break/junhong_cmp_fiber/internal/service/package"
	pollingSvc "github.com/break/junhong_cmp_fiber/internal/service/polling"
	purchaseValidationSvc "github.com/break/junhong_cmp_fiber/internal/service/purchase_validation"
	"github.com/break/junhong_cmp_fiber/pkg/queue"
)

type workerServices struct {
	CommissionCalculation *commission_calculation.Service
	CommissionStats       *commission_stats.Service
	UsageService          *packagepkg.UsageService
	ActivationService     *packagepkg.ActivationService
	ResetService          *packagepkg.ResetService
	AlertService          *pollingSvc.AlertService
	CleanupService        *pollingSvc.CleanupService
}

func initWorkerServices(stores *queue.WorkerStores, deps *WorkerDependencies) *queue.WorkerServices {
	assetAudit := assetAuditSvc.NewService(stores.AssetOperationLog, deps.DB)
	commissionStatsService := commission_stats.New(stores.ShopSeriesCommissionStats)

	commissionCalculationService := commission_calculation.New(
		deps.DB,
		stores.CommissionRecord,
		stores.Shop,
		stores.ShopPackageAllocation,
		stores.ShopSeriesAllocation,
		stores.PackageSeries,
		stores.IotCard,
		stores.Device,
		stores.AgentWallet,
		stores.AgentWalletTransaction,
		stores.Order,
		stores.OrderItem,
		stores.Package,
		stores.ShopSeriesCommissionStats,
		commissionStatsService,
		deps.Logger,
	)

	usageService := packagepkg.NewUsageService(
		deps.DB,
		deps.Redis,
		stores.PackageUsage,
		stores.PackageUsageDailyRecord,
		stores.DeviceSimBinding,
		deps.Logger,
	)

	activationService := packagepkg.NewActivationService(
		deps.DB,
		deps.Redis,
		stores.PackageUsage,
		stores.Package,
		stores.PackageUsageDailyRecord,
		deps.Logger,
	)

	resetService := packagepkg.NewResetService(
		deps.DB,
		deps.Redis,
		stores.PackageUsage,
		deps.Logger,
	)

	alertService := pollingSvc.NewAlertService(
		stores.PollingAlertRule,
		stores.PollingAlertHistory,
		deps.Redis,
		deps.Logger,
	)

	cleanupService := pollingSvc.NewCleanupService(
		stores.DataCleanupConfig,
		stores.DataCleanupLog,
		deps.Logger,
	)
	cardObservationOutbox := outbox.NewRepository()
	observationSeriesEvents := cardObservationInfra.NewSeriesEventWriter(cardObservationOutbox)
	cardObservationService := cardObservationApp.NewService(
		deps.DB,
		cardObservationInfra.NewEventWriter(cardObservationOutbox),
		cardObservationInfra.NewCacheInvalidator(deps.Redis, deps.Logger),
	)
	cardObservationIntegration := integrationlog.NewRepository(deps.DB)
	cardObservationSeriesCoordinator := cardObservationInfra.NewSeriesCoordinator(deps.Redis)
	cardObservationSeriesService := cardObservationApp.NewSeriesAttemptService(
		cardObservationSeriesCoordinator,
		cardObservationInfra.NewSeriesRunner(deps.DB, deps.GatewayClient, cardObservationService, cardObservationIntegration),
		cardObservationInfra.NewSeriesAttemptLogger(cardObservationIntegration),
	)

	// 初始化订单服务，供超时取消和批量订购共同复用现有订单规则。
	purchaseValidation := purchaseValidationSvc.New(deps.DB, stores.IotCard, stores.Device, stores.Package, stores.ShopPackageAllocation)
	orderService := orderSvc.New(
		deps.DB,
		deps.Redis,
		stores.Order,
		stores.OrderItem,
		stores.AgentWallet,
		stores.AssetWallet,
		nil, // paymentStore: 超时取消不需要
		purchaseValidation,
		stores.ShopPackageAllocation,
		stores.ShopSeriesAllocation,
		stores.IotCard,
		stores.Device,
		stores.PackageSeries,
		stores.PackageUsage,
		stores.Package,
		nil, // wechatConfigService: 超时取消不需要
		nil, // wechatPayment: 超时取消不需要
		nil, // paymentLoader: 超时取消不需要
		deps.QueueClient,
		deps.Logger,
		stores.AssetIdentifier,
		stores.PersonalCustomer,
		stores.PersonalCustomerPhone,
	)
	walletOutbox := outbox.NewRepository()
	walletDebitEvents := walletinfra.NewDebitEventWriter(walletOutbox)
	orderService.SetAgentWalletReservationService(walletapp.NewReservationService(walletinfra.NewReservationEventWriter(walletOutbox), walletDebitEvents, nil))
	orderService.SetAgentWalletDebitService(walletapp.NewDebitService(walletDebitEvents, nil))

	// 创建停复机服务并注入回调：流量耗尽自动停机、套餐激活/重置/支付后自动复机
	stopResumeService := iotCardSvc.NewStopResumeService(
		deps.Redis,
		stores.IotCard,
		stores.PackageUsage,
		stores.DeviceSimBinding,
		deps.GatewayClient,
		deps.Logger,
		assetAudit,
	)
	stopResumeService.SetObservationSeriesEventWriter(deps.DB, observationSeriesEvents)
	activationService.SetObservationSeriesEventWriter(observationSeriesEvents)
	usageService.SetStopResumeCallback(stopResumeService)
	activationService.SetResumeCallback(stopResumeService)
	orderService.SetResumeCallback(stopResumeService)
	resetService.SetResumeCallback(stopResumeService)
	deviceBatchAllocator := deviceSvc.New(
		deps.DB, deps.Redis, stores.Device, stores.DeviceSimBinding, stores.IotCard, stores.Shop,
		stores.AssetAllocationRecord, stores.ShopPackageAllocation, stores.ShopSeriesAllocation,
		stores.PackageSeries, deps.GatewayClient, stores.AssetIdentifier, assetAudit, nil, nil,
	)

	return &queue.WorkerServices{
		CardObservation:          cardObservationService,
		CardObservationSeries:    cardObservationSeriesService,
		ObservationSeriesEvents:  observationSeriesEvents,
		CommissionCalculation:    commissionCalculationService,
		CommissionStats:          commissionStatsService,
		UsageService:             usageService,
		ActivationService:        activationService,
		ResetService:             resetService,
		AlertService:             alertService,
		CleanupService:           cleanupService,
		StopResumeService:        stopResumeService,
		OrderExpirer:             orderService,
		AssetPackageOrderCreator: orderService,
		DeviceBatchAllocator:     deviceBatchAllocator,
	}
}
