package com.red.circle.other.app.command.activity.room.query;

import com.red.circle.other.app.dto.clientobject.activity.room.RoomRewardInfoCO;
import com.red.circle.other.app.enums.RoomRewardLevelEnum;
import com.red.circle.other.infra.database.mongo.entity.activity.RoomContributionActivityCount;
import com.red.circle.other.infra.database.mongo.service.activity.RoomContributionActivityCountService;
import com.red.circle.other.infra.utils.ZonedDateTimeUtils;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Optional;

/**
 * 房间奖励信息查询执行器
 *
 * @author system
 * @date 2025-12-01
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class RoomRewardInfoQryExe {

    private final RoomContributionActivityCountService roomContributionActivityCountService;

    public RoomRewardInfoCO execute(String roomId) {
        RoomRewardInfoCO result = new RoomRewardInfoCO();

        // 1. 计算倒计时
        result.setCountdown(calculateCountdown());

        // 2. 查询当前周数据
        Integer currentWeekDateNumber = ZonedDateTimeAsiaRiyadhUtils.getThisMonday();
        RoomContributionActivityCount currentWeek = findByRoomIdAndDateNumber(roomId, currentWeekDateNumber);
        result.setCurrentProgress(buildCurrentProgress(currentWeek));

        // 3. 查询上周数据
        String lastWeekDateNumber = ZonedDateTimeAsiaRiyadhUtils.getLastWeekMonday().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        RoomContributionActivityCount lastWeek = findByRoomIdAndDateNumber(roomId, Integer.parseInt(lastWeekDateNumber));
        result.setLastWeekProgress(buildLastWeekProgress(lastWeek));

        return result;
    }

    /**
     * 计算到下周一沙特时间0点的倒计时
     */
    private Timestamp calculateCountdown() {
        ZonedDateTime now = ZonedDateTimeAsiaRiyadhUtils.now();
        ZonedDateTime nextMonday = now.with(TemporalAdjusters.next(DayOfWeek.MONDAY))
                .withHour(0).withMinute(0).withSecond(0).withNano(0);
        return Timestamp.from(nextMonday.toInstant());
    }

    /**
     * 根据房间ID和日期查询数据
     */
    private RoomContributionActivityCount findByRoomIdAndDateNumber(String roomId, Integer dateNumber) {
        Long roomIdLong = Long.parseLong(roomId);
        return roomContributionActivityCountService
                .findByRoomIdAndDateNumber(roomIdLong, dateNumber)
                .orElse(null);
    }

    /**
     * 构建当前周进度
     */
    private RoomRewardInfoCO.CurrentProgressCO buildCurrentProgress(RoomContributionActivityCount data) {
        RoomRewardInfoCO.CurrentProgressCO progress = new RoomRewardInfoCO.CurrentProgressCO();
        
        if (data == null || data.getContributionValue() == null) {
            progress.setAmount(0L);
            progress.setLevel(null);
            return progress;
        }

        Long amount = data.getContributionValue().longValue();
        progress.setAmount(amount);

        RoomRewardLevelEnum level = RoomRewardLevelEnum.getLevelByAmount(amount);
        progress.setLevel(level != null ? level.getLevel() : null);

        return progress;
    }

    /**
     * 构建上周进度
     */
    private RoomRewardInfoCO.LastWeekProgressCO buildLastWeekProgress(RoomContributionActivityCount data) {
        RoomRewardInfoCO.LastWeekProgressCO progress = new RoomRewardInfoCO.LastWeekProgressCO();

        if (data == null || data.getContributionValue() == null) {
            progress.setAmount(0L);
            progress.setLevel(null);
            progress.setOwnerIncome(0L);
            progress.setOwnerIncomeReceived(false);
            progress.setRewardCoins(0L);
            progress.setRewardCoinsSent(false);
            return progress;
        }

        Long amount = data.getContributionValue().longValue();
        progress.setAmount(amount);

        // 计算等级
        RoomRewardLevelEnum level = RoomRewardLevelEnum.getLevelByAmount(amount);
        progress.setLevel(level != null ? level.getLevel() : null);

        // 计算房主收入（流水 * ratio）
        BigDecimal ratio = Optional.ofNullable(data.getRatio()).orElse(new BigDecimal("0.05"));
        Long ownerIncome = data.getContributionValue().multiply(ratio).longValue();
        progress.setOwnerIncome(ownerIncome);

        // 是否已领取
        progress.setOwnerIncomeReceived(Optional.ofNullable(data.getReceived()).orElse(false));

        // 奖励金币
        Long rewardCoins = level != null ? level.getRewardCoins() : 0L;
        progress.setRewardCoins(rewardCoins);

        // 奖励金币是否已发放
        progress.setRewardCoinsSent(Optional.ofNullable(data.getRewardCoinsSent()).orElse(false));

        return progress;
    }
}
