package com.red.circle.other.app.inner.endpoint.activity;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.infra.database.rds.entity.activity.LotteryActivity;
import com.red.circle.other.infra.database.rds.entity.activity.LotteryRecord;
import com.red.circle.other.infra.database.rds.service.activity.LotteryActivityService;
import com.red.circle.other.infra.database.rds.service.activity.LotteryRecordService;
import com.red.circle.other.inner.asserts.lottery.LotteryErrorCode;
import com.red.circle.other.inner.endpoint.activity.api.LotteryRecordManageClientApi;
import com.red.circle.other.inner.model.cmd.activity.LotteryRecordQryCmd;
import com.red.circle.other.inner.model.dto.activity.LotteryActivityDTO;
import com.red.circle.other.inner.model.dto.activity.LotteryRecordDTO;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.red.circle.tool.core.date.TimestampUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 中奖记录管理ClientEndpoint.
 *
 * @author system
 * @since 2025-10-18
 */
@Validated
@RestController
@RequestMapping(value = LotteryRecordManageClientApi.API_PREFIX, produces = MediaType.APPLICATION_JSON_VALUE)
@RequiredArgsConstructor
public class LotteryRecordManageClientEndpoint implements LotteryRecordManageClientApi {

  private final LotteryRecordService lotteryRecordService;
  private final LotteryActivityService lotteryActivityService;

  @Override
  public ResultResponse<PageResult<LotteryRecordDTO>> listRecords(LotteryRecordQryCmd cmd) {
    Integer pageNo = cmd.getPageNo() != null ? cmd.getPageNo() : 1;
    Integer pageSize = cmd.getPageSize() != null ? cmd.getPageSize() : 20;

    Page<LotteryRecord> page = new Page<>(pageNo, pageSize);
    var query = lotteryRecordService.query();

    if (cmd.getUserId() != null) {
      query.eq(LotteryRecord::getUserId, cmd.getUserId());
    }
    if (cmd.getActivityId() != null) {
      query.eq(LotteryRecord::getActivityId, cmd.getActivityId());
    }
    if (cmd.getActivityCode() != null) {
      LotteryActivity activity = lotteryActivityService.query()
          .eq(LotteryActivity::getActivityCode, cmd.getActivityCode())
          .getOne();
      if (activity != null) {
        query.eq(LotteryRecord::getActivityId, activity.getId());
      }
    }
    if (cmd.getIsWin() != null) {
      query.eq(LotteryRecord::getIsWin, cmd.getIsWin());
    }
    if (cmd.getPrizeStatus() != null) {
      query.eq(LotteryRecord::getPrizeStatus, cmd.getPrizeStatus());
    }
    if (cmd.getDrawTimeBegin() != null) {
      query.ge(LotteryRecord::getDrawTime, cmd.getDrawTimeBegin());
    }
    if (cmd.getDrawTimeEnd() != null) {
      query.le(LotteryRecord::getDrawTime, cmd.getDrawTimeEnd());
    }

    IPage<LotteryRecord> result = query.orderByDesc(LotteryRecord::getDrawTime).page(page);

    // 查询活动信息
    List<Long> activityIds = result.getRecords().stream()
        .map(LotteryRecord::getActivityId)
        .distinct()
        .collect(Collectors.toList());

    if (activityIds.isEmpty()) {
      return ResultResponse.success(PageResult.newPageResult(cmd.getPageSize()));
    }

    Map<Long, LotteryActivity> activityMap = lotteryActivityService.query()
        .in(LotteryActivity::getId, activityIds)
        .list()
        .stream()
        .collect(Collectors.toMap(LotteryActivity::getId, a -> a));

    List<LotteryRecordDTO> dtoList = result.getRecords().stream()
        .map(record -> {
          LotteryRecordDTO dto = new LotteryRecordDTO();
          BeanUtils.copyProperties(record, dto);
          
          LotteryActivity activity = activityMap.get(record.getActivityId());
          if (activity != null) {
            dto.setActivityName(activity.getActivityName());
          }
          
          return dto;
        })
        .collect(Collectors.toList());

    PageResult<LotteryRecordDTO> pageResult = new PageResult<>();
    pageResult.setCurrent(pageNo);
    pageResult.setSize(pageSize);
    pageResult.setTotal(result.getTotal());
    pageResult.setRecords(dtoList);
    return ResultResponse.success(pageResult);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public ResultResponse<Void> deliverPrize(Long recordId) {
    LotteryRecord record = lotteryRecordService.getById(recordId);
    ResponseAssert.isTrue(LotteryErrorCode.RECORD_NOT_FOUND, record != null);
    ResponseAssert.isTrue(LotteryErrorCode.NOT_WIN, record.getIsWin() == 1);
    ResponseAssert.isTrue(LotteryErrorCode.PRIZE_ALREADY_DELIVERED, record.getPrizeStatus() == 0);

    // TODO: 根据奖品类型执行不同的发放逻辑
    // 1-实物：生成发货单
    // 2-虚拟币：调用钱包服务
    // 3-优惠券：调用优惠券服务
    // 4-积分：调用积分服务

    record.setPrizeStatus(1); // 已发放
    record.setDeliverTime(TimestampUtils.now());
    lotteryRecordService.updateSelectiveById(record);
    
    return ResultResponse.success();
  }

}
