package com.red.circle.other.app.command.redpacket.query;

import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.other.app.convertor.RoomRedPacketAppConvertor;
import com.red.circle.other.app.dto.clientobject.RoomRedPacketDetailCO;
import com.red.circle.other.app.dto.clientobject.RoomRedPacketRecordCO;
import com.red.circle.other.app.dto.cmd.QueryRoomRedPacketDetailCmd;
import com.red.circle.other.domain.gateway.RoomRedPacketGateway;
import com.red.circle.other.domain.gateway.RoomRedPacketRecordGateway;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.domain.redpacket.RoomRedPacket;
import com.red.circle.other.domain.redpacket.RoomRedPacketRecord;
import com.red.circle.other.infra.database.cache.service.other.RoomRedPacketCacheService;
import com.red.circle.other.inner.asserts.OtherErrorCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 查询红包详情执行器
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class QueryRoomRedPacketDetailQryExe {

    private final RoomRedPacketGateway roomRedPacketGateway;
    private final RoomRedPacketRecordGateway roomRedPacketRecordGateway;
    private final RoomRedPacketCacheService roomRedPacketCacheService;
    private final UserProfileGateway userProfileGateway;

    /**
     * 执行查询
     */
    public RoomRedPacketDetailCO execute(QueryRoomRedPacketDetailCmd cmd) {
        Long userId = cmd.getReqUserId();
        String packetId = cmd.getPacketId();
        
        // 1. 查询红包信息
        RoomRedPacket redPacket = roomRedPacketGateway.findByPacketId(packetId);
        ResponseAssert.notNull(OtherErrorCode.RED_PACKET_NOT_FOUND, redPacket);

        // 2. 查询领取记录列表
        List<RoomRedPacketRecord> records = roomRedPacketRecordGateway.findByPacketId(packetId);
        
        // 3. 转换为CO
        RoomRedPacketDetailCO detailCO = RoomRedPacketAppConvertor.toDetailCO(redPacket, records);
        
        // 4. 检查当前用户是否已领取
        boolean grabbed = roomRedPacketCacheService.hasUserGrabbed(packetId, userId);
        detailCO.setGrabbed(grabbed);

        Set<Long> userIdSet = detailCO.getRecords().stream().map(RoomRedPacketRecordCO::getUserId).collect(Collectors.toSet());
        userIdSet.add(detailCO.getUserId());

        Map<Long, UserProfile> profileMap = userProfileGateway.mapByUserIds(userIdSet);
        UserProfile userProfile = profileMap.get(detailCO.getUserId());
        if (userProfile != null) {
            detailCO.setUserId(userProfile.getId());
            detailCO.setAccount(userProfile.getAccount());
            detailCO.setUserName(userProfile.getUserNickname());
            detailCO.setUserAvatar(userProfile.getUserAvatar());
        }

        detailCO.getRecords().forEach(roomRedPacketRecord -> {
            UserProfile profile = profileMap.get(roomRedPacketRecord.getUserId());
            if (profile != null) {
                roomRedPacketRecord.setUserId(profile.getId());
                roomRedPacketRecord.setAccount(profile.getAccount());
                roomRedPacketRecord.setUserName(profile.getUserNickname());
                roomRedPacketRecord.setUserAvatar(profile.getUserAvatar());
            };
        });

        // 5. 如果当前用户已领取，设置领取金额
        if (grabbed) {
            Optional<RoomRedPacketRecord> myRecord = records.stream()
                    .filter(r -> userId.equals(r.getUserId()))
                    .findFirst();
            myRecord.ifPresent(record -> detailCO.setMyAmount(record.getAmount()));
        }
        
        return detailCO;
    }
}
