package postgres

import (
	"context"

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

// AgentRechargeStore 代理充值记录数据访问层
type AgentRechargeStore struct {
	db    *gorm.DB
	redis *redis.Client
}

// NewAgentRechargeStore 创建代理充值记录 Store
func NewAgentRechargeStore(db *gorm.DB, redis *redis.Client) *AgentRechargeStore {
	return &AgentRechargeStore{
		db:    db,
		redis: redis,
	}
}

// Create 创建充值记录
func (s *AgentRechargeStore) Create(ctx context.Context, record *model.AgentRechargeRecord) error {
	return s.db.WithContext(ctx).Create(record).Error
}

// CreateWithTx 创建充值记录（带事务）
func (s *AgentRechargeStore) CreateWithTx(ctx context.Context, tx *gorm.DB, record *model.AgentRechargeRecord) error {
	return tx.WithContext(ctx).Create(record).Error
}

// GetByRechargeNo 根据充值订单号查询
func (s *AgentRechargeStore) GetByRechargeNo(ctx context.Context, rechargeNo string) (*model.AgentRechargeRecord, error) {
	var record model.AgentRechargeRecord
	err := s.db.WithContext(ctx).
		Where("recharge_no = ?", rechargeNo).
		First(&record).Error
	if err != nil {
		return nil, err
	}
	return &record, nil
}

// GetByID 根据 ID 查询
func (s *AgentRechargeStore) GetByID(ctx context.Context, id uint) (*model.AgentRechargeRecord, error) {
	var record model.AgentRechargeRecord
	if err := s.db.WithContext(ctx).First(&record, id).Error; err != nil {
		return nil, err
	}
	return &record, nil
}

// UpdateStatus 更新充值状态
func (s *AgentRechargeStore) UpdateStatus(ctx context.Context, id uint, status int) error {
	return s.db.WithContext(ctx).
		Model(&model.AgentRechargeRecord{}).
		Where("id = ?", id).
		Update("status", status).Error
}

// UpdateStatusWithTx 更新充值状态（带事务）
func (s *AgentRechargeStore) UpdateStatusWithTx(ctx context.Context, tx *gorm.DB, id uint, status int) error {
	return tx.WithContext(ctx).
		Model(&model.AgentRechargeRecord{}).
		Where("id = ?", id).
		Update("status", status).Error
}

// Update 更新充值记录
func (s *AgentRechargeStore) Update(ctx context.Context, record *model.AgentRechargeRecord) error {
	return s.db.WithContext(ctx).Save(record).Error
}

// UpdateStatusWithRejection 条件更新状态为已驳回并写入驳回原因
// 仅当 status = 1（待支付）时更新，RowsAffected=0 说明订单不存在或状态已变更
func (s *AgentRechargeStore) UpdateStatusWithRejection(ctx context.Context, id uint, rejectionReason string) error {
	result := s.db.WithContext(ctx).
		Model(&model.AgentRechargeRecord{}).
		Where("id = ? AND status = ?", id, constants.RechargeStatusPending).
		Updates(map[string]interface{}{
			"status":           constants.RechargeStatusRejected,
			"rejection_reason": rejectionReason,
		})
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return gorm.ErrRecordNotFound
	}
	return nil
}

// UpdateWithTx 更新充值记录（带事务）
func (s *AgentRechargeStore) UpdateWithTx(ctx context.Context, tx *gorm.DB, record *model.AgentRechargeRecord) error {
	return tx.WithContext(ctx).Save(record).Error
}

// ListByShopID 按店铺查询充值记录（支持分页）
func (s *AgentRechargeStore) ListByShopID(ctx context.Context, shopID uint, offset, limit int) ([]*model.AgentRechargeRecord, error) {
	var records []*model.AgentRechargeRecord
	err := s.db.WithContext(ctx).
		Where("shop_id = ?", shopID).
		Order("created_at DESC").
		Offset(offset).
		Limit(limit).
		Find(&records).Error
	if err != nil {
		return nil, err
	}
	return records, nil
}

// ListByUserID 按用户查询充值记录（支持分页）
func (s *AgentRechargeStore) ListByUserID(ctx context.Context, userID uint, offset, limit int) ([]*model.AgentRechargeRecord, error) {
	var records []*model.AgentRechargeRecord
	err := s.db.WithContext(ctx).
		Where("user_id = ?", userID).
		Order("created_at DESC").
		Offset(offset).
		Limit(limit).
		Find(&records).Error
	if err != nil {
		return nil, err
	}
	return records, nil
}

// ListByStatus 按状态查询充值记录（支持分页）
func (s *AgentRechargeStore) ListByStatus(ctx context.Context, status int, offset, limit int) ([]*model.AgentRechargeRecord, error) {
	var records []*model.AgentRechargeRecord
	err := s.db.WithContext(ctx).
		Where("status = ?", status).
		Order("created_at DESC").
		Offset(offset).
		Limit(limit).
		Find(&records).Error
	if err != nil {
		return nil, err
	}
	return records, nil
}
