package wallet

import (
	"context"
	"hyapp/pkg/appcode"
	"hyapp/pkg/xerr"
	"hyapp/services/wallet-service/internal/domain/ledger"
	"strings"
	"time"
)

// ProcessHostSalarySettlementBatch 执行主播/代理工资结算批处理；日结和半月结不清空周期钻石，月底只做逻辑清算标记。
func (s *Service) ProcessHostSalarySettlementBatch(ctx context.Context, command ledger.HostSalarySettlementBatchCommand) (ledger.HostSalarySettlementBatchResult, error) {
	if s.repository == nil {
		return ledger.HostSalarySettlementBatchResult{}, xerr.New(xerr.Unavailable, "wallet repository is not configured")
	}
	switch strings.TrimSpace(command.SettlementType) {
	case ledger.HostSalarySettlementModeDaily, ledger.HostSalarySettlementModeHalfMonth, ledger.HostSalarySettlementTypeMonthEnd:
	default:
		return ledger.HostSalarySettlementBatchResult{}, xerr.New(xerr.InvalidArgument, "settlement_type is invalid")
	}
	if command.BatchSize <= 0 {
		command.BatchSize = 100
	}
	if command.BatchSize > 500 {
		command.BatchSize = 500
	}
	if strings.TrimSpace(command.RunID) == "" || strings.TrimSpace(command.WorkerID) == "" {
		return ledger.HostSalarySettlementBatchResult{}, xerr.New(xerr.InvalidArgument, "run_id and worker_id are required")
	}
	command.AppCode = appcode.Normalize(command.AppCode)
	if command.NowMs <= 0 {
		command.NowMs = s.now().UTC().UnixMilli()
	}
	if strings.TrimSpace(command.CycleKey) == "" {
		command.CycleKey = hostSalaryCycleKey(command.NowMs)
	}
	ctx = appcode.WithContext(ctx, command.AppCode)
	return s.repository.ProcessHostSalarySettlementBatch(ctx, command)
}

func hostSalaryCycleKey(nowMs int64) string {
	// 结算周期按 UTC 月锚定，和送礼入账的 host_period_diamond_accounts.cycle_key 保持同一口径。
	return time.UnixMilli(nowMs).UTC().Format("2006-01")
}

// GetActiveHostSalaryPolicy 读取主播所在区域当前生效的工资政策，返回的 policy 与工资结算使用同一张 runtime 表。
func (s *Service) GetActiveHostSalaryPolicy(ctx context.Context, appCode string, regionID int64, settlementMode string, triggerMode string, nowMs int64) (ledger.HostSalaryPolicy, bool, error) {
	if regionID <= 0 {
		return ledger.HostSalaryPolicy{}, false, xerr.New(xerr.InvalidArgument, "region_id is required")
	}
	if s.repository == nil {
		return ledger.HostSalaryPolicy{}, false, xerr.New(xerr.Unavailable, "wallet repository is not configured")
	}
	settlementMode = strings.TrimSpace(settlementMode)
	if settlementMode != "" && settlementMode != ledger.HostSalarySettlementModeDaily && settlementMode != ledger.HostSalarySettlementModeHalfMonth {
		return ledger.HostSalaryPolicy{}, false, xerr.New(xerr.InvalidArgument, "settlement_mode is invalid")
	}
	triggerMode = strings.TrimSpace(triggerMode)
	if triggerMode != "" && triggerMode != ledger.HostSalarySettlementTriggerAutomatic && triggerMode != ledger.HostSalarySettlementTriggerManual {
		return ledger.HostSalaryPolicy{}, false, xerr.New(xerr.InvalidArgument, "settlement_trigger_mode is invalid")
	}
	if nowMs <= 0 {
		nowMs = s.now().UTC().UnixMilli()
	}
	appCode = appcode.Normalize(appCode)
	ctx = appcode.WithContext(ctx, appCode)
	// H5 展示可以不传 trigger mode，此时 automatic/manual 政策都可展示；结算任务仍会传具体 trigger 精确匹配。
	return s.repository.GetActiveHostSalaryPolicy(ctx, regionID, settlementMode, triggerMode, nowMs)
}

// GetHostSalaryProgress 返回主播当前工资周期的钻石累计；没有收礼账户时返回 0，避免 H5 用其他等级系统兜底导致进度口径错误。
func (s *Service) GetHostSalaryProgress(ctx context.Context, appCode string, userID int64, cycleKey string, nowMs int64) (ledger.HostSalaryProgress, error) {
	if userID <= 0 {
		return ledger.HostSalaryProgress{}, xerr.New(xerr.InvalidArgument, "host_user_id is required")
	}
	if s.repository == nil {
		return ledger.HostSalaryProgress{}, xerr.New(xerr.Unavailable, "wallet repository is not configured")
	}
	if nowMs <= 0 {
		nowMs = s.now().UTC().UnixMilli()
	}
	cycleKey = strings.TrimSpace(cycleKey)
	if cycleKey == "" {
		cycleKey = hostSalaryCycleKey(nowMs)
	}
	appCode = appcode.Normalize(appCode)
	ctx = appcode.WithContext(ctx, appCode)
	return s.repository.GetHostSalaryProgress(ctx, userID, cycleKey)
}
