package postgres

import (
	"context"
	"time"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/internal/store"
	"github.com/break/junhong_cmp_fiber/pkg/constants"
	"github.com/break/junhong_cmp_fiber/pkg/middleware"
	"github.com/redis/go-redis/v9"
	"gorm.io/gorm"
)

type CommissionRecordWithRelations struct {
	model.CommissionRecord
	OrderNo        string     `gorm:"column:order_no"`
	OrderCreatedAt *time.Time `gorm:"column:order_created_at"`
	ICCID          string     `gorm:"column:iccid"`
	VirtualNo      string     `gorm:"column:virtual_no"`
	SellerShopID   *uint      `gorm:"column:seller_shop_id"`
}

type CommissionRecordStore struct {
	db    *gorm.DB
	redis *redis.Client
}

func NewCommissionRecordStore(db *gorm.DB, redis *redis.Client) *CommissionRecordStore {
	return &CommissionRecordStore{
		db:    db,
		redis: redis,
	}
}

func (s *CommissionRecordStore) Create(ctx context.Context, record *model.CommissionRecord) error {
	return s.db.WithContext(ctx).Create(record).Error
}

func (s *CommissionRecordStore) UpdateByID(ctx context.Context, tx *gorm.DB, id uint, updates map[string]any) error {
	db := s.db
	if tx != nil {
		db = tx
	}
	return db.WithContext(ctx).Model(&model.CommissionRecord{}).Where("id = ?", id).Updates(updates).Error
}

func (s *CommissionRecordStore) GetByID(ctx context.Context, id uint) (*model.CommissionRecord, error) {
	var record model.CommissionRecord
	query := s.db.WithContext(ctx).Where("id = ?", id)
	// 应用数据权限过滤
	query = middleware.ApplyShopFilter(ctx, query)
	if err := query.First(&record).Error; err != nil {
		return nil, err
	}
	return &record, nil
}

type CommissionRecordListFilters struct {
	ShopID           uint
	CommissionSource string
	ICCID            string
	DeviceNo         string
	OrderNo          string
	StartTime        *string
	EndTime          *string
	Status           *int
}

func (s *CommissionRecordStore) ListByShopID(ctx context.Context, opts *store.QueryOptions, filters *CommissionRecordListFilters) ([]*CommissionRecordWithRelations, int64, error) {
	var total int64

	query := s.db.WithContext(ctx).Model(&model.CommissionRecord{}).
		Joins("LEFT JOIN tb_order o ON tb_commission_record.order_id = o.id AND o.deleted_at IS NULL").
		Joins("LEFT JOIN tb_iot_card ic ON tb_commission_record.iot_card_id = ic.id AND ic.deleted_at IS NULL").
		Joins("LEFT JOIN tb_device d ON tb_commission_record.device_id = d.id AND d.deleted_at IS NULL")
	if shopIDs := middleware.GetSubordinateShopIDs(ctx); len(shopIDs) > 0 {
		query = query.Where("tb_commission_record.shop_id IN ?", shopIDs)
	}

	if filters != nil {
		if filters.ShopID > 0 {
			query = query.Where("tb_commission_record.shop_id = ?", filters.ShopID)
		}
		if filters.CommissionSource != "" {
			query = query.Where("tb_commission_record.commission_source = ?", filters.CommissionSource)
		}
		if filters.StartTime != nil && *filters.StartTime != "" {
			query = query.Where("tb_commission_record.created_at >= ?", *filters.StartTime)
		}
		if filters.EndTime != nil && *filters.EndTime != "" {
			query = query.Where("tb_commission_record.created_at <= ?", *filters.EndTime)
		}
		if filters.Status != nil {
			query = query.Where("tb_commission_record.status = ?", *filters.Status)
		}
		if filters.ICCID != "" {
			query = query.Where("ic.iccid LIKE ?", "%"+filters.ICCID+"%")
		}
		if filters.OrderNo != "" {
			query = query.Where("o.order_no = ?", filters.OrderNo)
		}
		if filters.DeviceNo != "" {
			query = query.Where("d.virtual_no LIKE ?", "%"+filters.DeviceNo+"%")
		}
	}

	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	if opts == nil {
		opts = &store.QueryOptions{
			Page:     1,
			PageSize: constants.DefaultPageSize,
		}
	}
	offset := (opts.Page - 1) * opts.PageSize
	query = query.Select(`tb_commission_record.*, o.order_no, o.created_at as order_created_at, o.seller_shop_id, ic.iccid, d.virtual_no`)
	query = query.Offset(offset).Limit(opts.PageSize)

	if opts.OrderBy != "" {
		query = query.Order(opts.OrderBy)
	} else {
		query = query.Order("tb_commission_record.created_at DESC")
	}

	var records []*CommissionRecordWithRelations
	if err := query.Find(&records).Error; err != nil {
		return nil, 0, err
	}

	return records, total, nil
}

type CommissionStats struct {
	TotalAmount    int64
	CostDiffAmount int64
	OneTimeAmount  int64
	TotalCount     int64
	CostDiffCount  int64
	OneTimeCount   int64
}

func (s *CommissionRecordStore) GetStats(ctx context.Context, filters *CommissionRecordListFilters) (*CommissionStats, error) {
	query := s.db.WithContext(ctx).Model(&model.CommissionRecord{}).
		Where("status NOT IN (?)", []int{constants.CommissionStatusInvalid, constants.CommissionStatusPendingReview})
	// 应用数据权限过滤
	query = middleware.ApplyShopFilter(ctx, query)

	if filters != nil {
		if filters.ShopID > 0 {
			query = query.Where("shop_id = ?", filters.ShopID)
		}
		if filters.StartTime != nil && *filters.StartTime != "" {
			query = query.Where("created_at >= ?", *filters.StartTime)
		}
		if filters.EndTime != nil && *filters.EndTime != "" {
			query = query.Where("created_at <= ?", *filters.EndTime)
		}
	}

	var stats CommissionStats

	result := query.Select(`
		COALESCE(SUM(amount), 0) as total_amount,
		COALESCE(SUM(CASE WHEN commission_source = 'cost_diff' THEN amount ELSE 0 END), 0) as cost_diff_amount,
		COALESCE(SUM(CASE WHEN commission_source = 'one_time' THEN amount ELSE 0 END), 0) as one_time_amount,
		COUNT(*) as total_count,
		COALESCE(SUM(CASE WHEN commission_source = 'cost_diff' THEN 1 ELSE 0 END), 0) as cost_diff_count,
		COALESCE(SUM(CASE WHEN commission_source = 'one_time' THEN 1 ELSE 0 END), 0) as one_time_count
	`).Scan(&stats)

	if result.Error != nil {
		return nil, result.Error
	}

	return &stats, nil
}

type DailyCommissionStats struct {
	Date        string
	TotalAmount int64
	TotalCount  int64
}

func (s *CommissionRecordStore) GetDailyStats(ctx context.Context, filters *CommissionRecordListFilters, days int) ([]*DailyCommissionStats, error) {
	if days <= 0 {
		days = 30
	}

	query := s.db.WithContext(ctx).Model(&model.CommissionRecord{}).
		Where("status NOT IN (?)", []int{constants.CommissionStatusInvalid, constants.CommissionStatusPendingReview})
	// 应用数据权限过滤
	query = middleware.ApplyShopFilter(ctx, query)

	if filters != nil {
		if filters.ShopID > 0 {
			query = query.Where("shop_id = ?", filters.ShopID)
		}
		if filters.StartTime != nil && *filters.StartTime != "" {
			query = query.Where("created_at >= ?", *filters.StartTime)
		}
		if filters.EndTime != nil && *filters.EndTime != "" {
			query = query.Where("created_at <= ?", *filters.EndTime)
		}
	}

	var stats []*DailyCommissionStats

	result := query.Select(`
		DATE(created_at) as date,
		COALESCE(SUM(amount), 0) as total_amount,
		COUNT(*) as total_count
	`).
		Group("DATE(created_at)").
		Order("date DESC").
		Limit(days).
		Scan(&stats)

	if result.Error != nil {
		return nil, result.Error
	}

	return stats, nil
}
