package postgres

import (
	"context"
	"time"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"gorm.io/gorm"
)

type ShopSeriesCommissionStatsStore struct {
	db *gorm.DB
}

func NewShopSeriesCommissionStatsStore(db *gorm.DB) *ShopSeriesCommissionStatsStore {
	return &ShopSeriesCommissionStatsStore{db: db}
}

func (s *ShopSeriesCommissionStatsStore) Create(ctx context.Context, stats *model.ShopSeriesCommissionStats) error {
	return s.db.WithContext(ctx).Create(stats).Error
}

func (s *ShopSeriesCommissionStatsStore) GetCurrent(ctx context.Context, allocationID uint, periodType string, now time.Time) (*model.ShopSeriesCommissionStats, error) {
	var stats model.ShopSeriesCommissionStats
	err := s.db.WithContext(ctx).
		Where("allocation_id = ?", allocationID).
		Where("period_type = ?", periodType).
		Where("period_start <= ? AND period_end >= ?", now, now).
		Where("status = ?", model.StatsStatusActive).
		First(&stats).Error
	if err != nil {
		return nil, err
	}
	return &stats, nil
}

func (s *ShopSeriesCommissionStatsStore) Update(ctx context.Context, stats *model.ShopSeriesCommissionStats) error {
	return s.db.WithContext(ctx).Save(stats).Error
}

func (s *ShopSeriesCommissionStatsStore) IncrementSales(ctx context.Context, id uint, salesCount int64, salesAmount int64, version int) error {
	return s.db.WithContext(ctx).
		Model(&model.ShopSeriesCommissionStats{}).
		Where("id = ? AND version = ?", id, version).
		Updates(map[string]interface{}{
			"total_sales_count":  gorm.Expr("total_sales_count + ?", salesCount),
			"total_sales_amount": gorm.Expr("total_sales_amount + ?", salesAmount),
			"last_updated_at":    time.Now(),
			"version":            gorm.Expr("version + 1"),
		}).Error
}

func (s *ShopSeriesCommissionStatsStore) CompletePeriod(ctx context.Context, id uint) error {
	return s.db.WithContext(ctx).
		Model(&model.ShopSeriesCommissionStats{}).
		Where("id = ?", id).
		Update("status", model.StatsStatusCompleted).Error
}

func (s *ShopSeriesCommissionStatsStore) ListExpired(ctx context.Context, before time.Time) ([]*model.ShopSeriesCommissionStats, error) {
	var stats []*model.ShopSeriesCommissionStats
	err := s.db.WithContext(ctx).
		Where("period_end < ?", before).
		Where("status = ?", model.StatsStatusActive).
		Find(&stats).Error
	if err != nil {
		return nil, err
	}
	return stats, nil
}

func (s *ShopSeriesCommissionStatsStore) GetAggregatedStats(ctx context.Context, allocationIDs []uint, periodType string, now time.Time) (int64, int64, error) {
	if len(allocationIDs) == 0 {
		return 0, 0, nil
	}

	var result struct {
		TotalSalesCount  int64
		TotalSalesAmount int64
	}

	err := s.db.WithContext(ctx).
		Model(&model.ShopSeriesCommissionStats{}).
		Select("COALESCE(SUM(total_sales_count), 0) as total_sales_count, COALESCE(SUM(total_sales_amount), 0) as total_sales_amount").
		Where("allocation_id IN ?", allocationIDs).
		Where("period_type = ?", periodType).
		Where("period_start <= ? AND period_end >= ?", now, now).
		Where("status = ?", model.StatsStatusActive).
		Scan(&result).Error

	if err != nil {
		return 0, 0, err
	}

	return result.TotalSalesCount, result.TotalSalesAmount, nil
}
