package user

import (
	"context"
	"errors"
	"time"

	"bindbox-game/internal/repository/mysql/model"

	"gorm.io/gorm"
)

// AddItemCard 给用户添加道具卡
// 功能描述：
//   - 根据道具卡模板ID查询模板信息
//   - 验证道具卡状态是否有效（status=1）
//   - 创建用户道具卡记录，继承模板的有效期设置
//   - 支持批量添加，quantity参数控制数量
//
// 参数说明：
//   - ctx: 上下文
//   - userID: 用户ID
//   - cardID: 道具卡模板ID
//   - quantity: 添加数量，如果<=0则默认为1
//
// 返回说明：
//   - error: 错误信息，包括数据库查询失败、模板不存在等情况
func (s *service) AddItemCard(ctx context.Context, userID int64, cardID int64, quantity int) error {
	if quantity <= 0 {
		quantity = 1
	}
	if quantity > 100 {
		quantity = 100
	}
	tpl, err := s.readDB.SystemItemCards.WithContext(ctx).Where(s.readDB.SystemItemCards.ID.Eq(cardID)).First()
	if err != nil {
		return err
	}
	if tpl == nil || tpl.Status != 1 {
		return errors.New("item card not found or disabled")
	}
	// 用户持有上限：不做限制
	now := time.Now()
	for i := 0; i < quantity; i++ {
		item := &model.UserItemCards{UserID: userID, CardID: cardID, Status: 1}
		if !tpl.ValidStart.IsZero() {
			item.ValidStart = tpl.ValidStart
		} else {
			item.ValidStart = now
		}
		if !tpl.ValidEnd.IsZero() {
			item.ValidEnd = tpl.ValidEnd
		}
		do := s.writeDB.UserItemCards.WithContext(ctx)
		// 避免写入未使用相关字段的零值，触发 MySQL 时间字段校验错误
		do = do.Omit(
			s.writeDB.UserItemCards.UsedAt,
			s.writeDB.UserItemCards.UsedDrawLogID,
			s.writeDB.UserItemCards.UsedActivityID,
			s.writeDB.UserItemCards.UsedIssueID,
		)
		if tpl.ValidEnd.IsZero() {
			do = do.Omit(s.writeDB.UserItemCards.ValidEnd)
		}
		if err := do.Create(item); err != nil {
			return err
		}
	}
	return nil
}

func (s *service) VoidUserItemCard(ctx context.Context, adminID int64, userID int64, userItemCardID int64) error {
	if userID <= 0 || userItemCardID <= 0 {
		return gorm.ErrInvalidData
	}
	uc, err := s.readDB.UserItemCards.WithContext(ctx).
		Where(s.readDB.UserItemCards.ID.Eq(userItemCardID)).
		Where(s.readDB.UserItemCards.UserID.Eq(userID)).
		First()
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return gorm.ErrRecordNotFound
		}
		return err
	}
	if uc.Status != 1 {
		return gorm.ErrInvalidData
	}
	db := s.repo.GetDbW()
	if err := db.Exec("UPDATE user_item_cards SET status=3, updated_at=NOW(3), remark=CONCAT(IFNULL(remark,''),'|void_by_admin') WHERE id=? AND user_id=? AND status=1", userItemCardID, userID).Error; err != nil {
		return err
	}
	_ = adminID
	return nil
}
