package commission_stats

import (
	"context"
	"time"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/internal/store/postgres"
	"github.com/break/junhong_cmp_fiber/pkg/errors"
	"gorm.io/gorm"
)

type Service struct {
	statsStore *postgres.ShopSeriesCommissionStatsStore
}

func New(statsStore *postgres.ShopSeriesCommissionStatsStore) *Service {
	return &Service{
		statsStore: statsStore,
	}
}

func (s *Service) GetCurrentStats(ctx context.Context, allocationID uint, periodType string) (*model.ShopSeriesCommissionStats, error) {
	now := time.Now()

	stats, err := s.statsStore.GetCurrent(ctx, allocationID, periodType, now)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, errors.New(errors.CodeNotFound, "统计数据不存在")
		}
		return nil, errors.Wrap(errors.CodeInternalError, err, "获取统计数据失败")
	}

	return stats, nil
}

func (s *Service) UpdateStats(ctx context.Context, allocationID uint, periodType string, salesCount int64, salesAmount int64) error {
	now := time.Now()
	periodStart, periodEnd := calculatePeriod(now, periodType)

	stats, err := s.statsStore.GetCurrent(ctx, allocationID, periodType, now)
	if err != nil && err != gorm.ErrRecordNotFound {
		return errors.Wrap(errors.CodeInternalError, err, "查询统计数据失败")
	}

	if stats == nil {
		stats = &model.ShopSeriesCommissionStats{
			AllocationID:     allocationID,
			PeriodType:       periodType,
			PeriodStart:      periodStart,
			PeriodEnd:        periodEnd,
			TotalSalesCount:  salesCount,
			TotalSalesAmount: salesAmount,
			Status:           "active",
			LastUpdatedAt:    now,
			Version:          1,
		}
		return s.statsStore.Create(ctx, stats)
	}

	return s.statsStore.IncrementSales(ctx, stats.ID, salesCount, salesAmount, stats.Version)
}

func (s *Service) ArchiveCompletedPeriod(ctx context.Context, allocationID uint, periodType string) error {
	now := time.Now()
	stats, err := s.statsStore.GetCurrent(ctx, allocationID, periodType, now)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil
		}
		return errors.Wrap(errors.CodeInternalError, err, "查询统计数据失败")
	}

	return s.statsStore.CompletePeriod(ctx, stats.ID)
}

func calculatePeriod(now time.Time, periodType string) (time.Time, time.Time) {
	var periodStart, periodEnd time.Time

	switch periodType {
	case "monthly":
		periodStart = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
		periodEnd = periodStart.AddDate(0, 1, 0).Add(-time.Second)
	case "quarterly":
		quarter := (int(now.Month()) - 1) / 3
		periodStart = time.Date(now.Year(), time.Month(quarter*3+1), 1, 0, 0, 0, 0, now.Location())
		periodEnd = periodStart.AddDate(0, 3, 0).Add(-time.Second)
	case "yearly":
		periodStart = time.Date(now.Year(), 1, 1, 0, 0, 0, 0, now.Location())
		periodEnd = periodStart.AddDate(1, 0, 0).Add(-time.Second)
	default:
		periodStart = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
		periodEnd = periodStart.AddDate(0, 1, 0).Add(-time.Second)
	}

	return periodStart, periodEnd
}
