package postgres

import (
	"context"

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

// WechatConfigStore 微信参数配置数据访问层
type WechatConfigStore struct {
	db  *gorm.DB
	rdb *redis.Client
}

// NewWechatConfigStore 创建微信参数配置 Store 实例
func NewWechatConfigStore(db *gorm.DB, rdb *redis.Client) *WechatConfigStore {
	return &WechatConfigStore{db: db, rdb: rdb}
}

// Create 创建微信参数配置
func (s *WechatConfigStore) Create(ctx context.Context, config *model.WechatConfig) error {
	return s.db.WithContext(ctx).Create(config).Error
}

// GetByID 根据 ID 获取配置（遵循软删除）
func (s *WechatConfigStore) GetByID(ctx context.Context, id uint) (*model.WechatConfig, error) {
	var config model.WechatConfig
	if err := s.db.WithContext(ctx).First(&config, id).Error; err != nil {
		return nil, err
	}
	return &config, nil
}

// GetByIDUnscoped 根据 ID 获取配置（包含已软删除的记录，用于回调处理）
func (s *WechatConfigStore) GetByIDUnscoped(ctx context.Context, id uint) (*model.WechatConfig, error) {
	var config model.WechatConfig
	if err := s.db.WithContext(ctx).Unscoped().First(&config, id).Error; err != nil {
		return nil, err
	}
	return &config, nil
}

// List 查询配置列表，支持按 provider_type 和 is_active 过滤
func (s *WechatConfigStore) List(ctx context.Context, opts *store.QueryOptions, filters map[string]interface{}) ([]*model.WechatConfig, int64, error) {
	var configs []*model.WechatConfig
	var total int64

	query := s.db.WithContext(ctx).Model(&model.WechatConfig{})

	if providerType, ok := filters["provider_type"].(string); ok && providerType != "" {
		query = query.Where("provider_type = ?", providerType)
	}
	if isActive, ok := filters["is_active"].(*bool); ok && isActive != nil {
		query = query.Where("is_active = ?", *isActive)
	}

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

	if opts == nil {
		opts = store.DefaultQueryOptions()
	}
	offset := (opts.Page - 1) * opts.PageSize
	query = query.Offset(offset).Limit(opts.PageSize)

	if opts.OrderBy != "" {
		query = query.Order(opts.OrderBy)
	}

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

	return configs, total, nil
}

// Update 更新微信参数配置
func (s *WechatConfigStore) Update(ctx context.Context, config *model.WechatConfig) error {
	return s.db.WithContext(ctx).Save(config).Error
}

// SoftDelete 软删除微信参数配置
func (s *WechatConfigStore) SoftDelete(ctx context.Context, id uint) error {
	return s.db.WithContext(ctx).Delete(&model.WechatConfig{}, id).Error
}

// GetActive 获取当前激活的配置
// 返回 gorm.ErrRecordNotFound 如果没有激活的配置
func (s *WechatConfigStore) GetActive(ctx context.Context) (*model.WechatConfig, error) {
	var config model.WechatConfig
	if err := s.db.WithContext(ctx).Where("is_active = ? AND deleted_at IS NULL", true).First(&config).Error; err != nil {
		return nil, err
	}
	return &config, nil
}

// ActivateInTx 在事务内激活指定配置（先停用所有，再激活指定记录）
func (s *WechatConfigStore) ActivateInTx(ctx context.Context, tx *gorm.DB, id uint) error {
	// 先锁定当前活跃记录，防止并发激活导致多条 is_active=true
	var current model.WechatConfig
	tx.WithContext(ctx).Clauses(clause.Locking{Strength: "UPDATE"}).
		Where("is_active = ?", true).
		First(&current)

	// 先停用所有激活的配置
	if err := tx.WithContext(ctx).Model(&model.WechatConfig{}).
		Where("is_active = ?", true).
		Update("is_active", false).Error; err != nil {
		return err
	}
	// 再激活指定配置
	return tx.WithContext(ctx).Model(&model.WechatConfig{}).
		Where("id = ?", id).
		Update("is_active", true).Error
}

// DB 返回底层数据库连接，用于事务操作
func (s *WechatConfigStore) DB() *gorm.DB {
	return s.db
}

// Deactivate 停用指定配置
func (s *WechatConfigStore) Deactivate(ctx context.Context, id uint) error {
	return s.db.WithContext(ctx).Model(&model.WechatConfig{}).
		Where("id = ?", id).
		Update("is_active", false).Error
}

// CountPendingOrdersByConfigID 统计指定配置的待支付订单数
func (s *WechatConfigStore) CountPendingOrdersByConfigID(ctx context.Context, configID uint) (int64, error) {
	var count int64
	err := s.db.WithContext(ctx).
		Table("tb_order").
		Where("payment_config_id = ? AND payment_status = ? AND deleted_at IS NULL", configID, 1).
		Count(&count).Error
	return count, err
}

// CountPendingRechargesByConfigID 统计指定配置的待支付充值记录数
func (s *WechatConfigStore) CountPendingRechargesByConfigID(ctx context.Context, configID uint) (int64, error) {
	var count int64
	err := s.db.WithContext(ctx).
		Table("tb_recharge_order").
		Where("payment_config_id = ? AND status = ? AND deleted_at IS NULL", configID, 1).
		Count(&count).Error
	return count, err
}
