package repository

import (
	"metazone.cc/metalab/internal/model"
	"metazone.cc/metalab/internal/service"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

// FundRepo 公户数据访问
type FundRepo struct {
	db *gorm.DB
}

// NewFundRepo 构造函数
func NewFundRepo(db *gorm.DB) *FundRepo {
	return &FundRepo{db: db}
}

// WithTx 基于给定事务连接创建新的 FundRepo
func (r *FundRepo) WithTx(tx *gorm.DB) service.FundStore {
	return &FundRepo{db: tx}
}

// GetBalance 查询公户余额
func (r *FundRepo) GetBalance() (int, error) {
	var fund model.CommunityFund
	err := r.db.First(&fund, 1).Error
	if err != nil {
		return 0, err
	}
	return fund.Balance, nil
}

// LockAndGetBalance 加行锁查询公户余额（事务内使用，防止 TOCTOU 竞态）
func (r *FundRepo) LockAndGetBalance() (int, error) {
	var fund model.CommunityFund
	err := r.db.Clauses(clause.Locking{Strength: "UPDATE"}).First(&fund, 1).Error
	if err != nil {
		return 0, err
	}
	return fund.Balance, nil
}

// IncrBalance 原子增减公户余额
func (r *FundRepo) IncrBalance(amount int) error {
	return r.db.Model(&model.CommunityFund{}).
		Where("id = 1").
		UpdateColumn("balance", gorm.Expr("balance + ?", amount)).Error
}

// CreateLog 创建公户流水
func (r *FundRepo) CreateLog(log *model.FundLog) error {
	return r.db.Create(log).Error
}

// ListLogs 分页查询公户流水
func (r *FundRepo) ListLogs(logType string, offset, limit int) ([]model.FundLog, int64, error) {
	query := r.db.Model(&model.FundLog{})
	if logType != "" {
		query = query.Where("type = ?", logType)
	}
	var total int64
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}
	var logs []model.FundLog
	err := query.Order("created_at DESC").Offset(offset).Limit(limit).Find(&logs).Error
	return logs, total, err
}
