package com.red.circle.other.app.inner.service.activity.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.red.circle.other.app.inner.service.activity.LotteryTicketClientService;
import com.red.circle.other.infra.database.rds.entity.activity.LotteryTicket;
import com.red.circle.other.infra.database.rds.entity.activity.LotteryTicketRecord;
import com.red.circle.other.infra.database.rds.service.activity.LotteryTicketRecordService;
import com.red.circle.other.infra.database.rds.service.activity.LotteryTicketService;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 抽奖券Client服务实现.
 *
 * @author system
 * @since 2025-10-21
 */
@Service
@RequiredArgsConstructor
public class LotteryTicketClientServiceImpl implements LotteryTicketClientService {

  private final LotteryTicketService lotteryTicketService;
  private final LotteryTicketRecordService lotteryTicketRecordService;

  @Override
  public Integer getUserTicketCount(Long userId) {
    List<LotteryTicket> tickets = lotteryTicketService.query()
        .eq(LotteryTicket::getUserId, userId)
        .eq(LotteryTicket::getStatus, 1)
        .gt(LotteryTicket::getRemainingCount, 0)
        .list();
    
    return tickets.stream()
        .mapToInt(LotteryTicket::getRemainingCount)
        .sum();
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Boolean deductTicket(Long userId, Integer count) {
    List<LotteryTicket> tickets = lotteryTicketService.query()
        .eq(LotteryTicket::getUserId, userId)
        .eq(LotteryTicket::getStatus, 1)
        .gt(LotteryTicket::getRemainingCount, 0)
        .orderByAsc(LotteryTicket::getExpireTime)
        .list();
    
    int totalRemaining = tickets.stream()
        .mapToInt(LotteryTicket::getRemainingCount)
        .sum();
    
    if (totalRemaining < count) {
      return false;
    }
    
    int remaining = count;
    for (LotteryTicket ticket : tickets) {
      if (remaining <= 0) {
        break;
      }
      
      int deduct = Math.min(remaining, ticket.getRemainingCount());

      LambdaUpdateWrapper<LotteryTicket> updateWrapper = new LambdaUpdateWrapper<LotteryTicket>()
          .eq(LotteryTicket::getId, ticket.getId())
          .setSql("used_count = used_count + " + deduct)
          .setSql("remaining_count = remaining_count - " + deduct);
      lotteryTicketService.update(updateWrapper);
      
      // 记录使用
      LotteryTicketRecord ticketRecord = new LotteryTicketRecord();
      ticketRecord.setUserId(userId);
      ticketRecord.setTicketId(ticket.getId());
      ticketRecord.setChangeCount(-deduct);
      ticketRecord.setChangeType(2); // 消耗
      ticketRecord.setRemark("抽奖消耗");
      lotteryTicketRecordService.save(ticketRecord);
      
      remaining -= deduct;
    }
    
    return true;
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Long addTicket(Long userId, Integer count, String source, String sourceId) {
    LotteryTicket ticket = new LotteryTicket();
    ticket.setUserId(userId);
    ticket.setTicketSource(source != null ? source : "SYSTEM");
    ticket.setSourceId(sourceId);
    ticket.setTotalCount(count);
    ticket.setUsedCount(0);
    ticket.setRemainingCount(count);
    ticket.setStatus(1);
    
    lotteryTicketService.save(ticket);
    
    // 记录发放
    LotteryTicketRecord ticketRecord = new LotteryTicketRecord();
    ticketRecord.setUserId(userId);
    ticketRecord.setTicketId(ticket.getId());
    ticketRecord.setChangeCount(count);
    ticketRecord.setChangeType(1); // 发放
    ticketRecord.setRemark("系统发放");
    lotteryTicketRecordService.save(ticketRecord);
    
    return ticket.getId();
  }

}
