package com.red.circle.other.app.command.signin;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.other.app.dto.clientobject.signin.SignInDailyConfigCO;
import com.red.circle.other.app.dto.clientobject.signin.SignInStatusCO;
import com.red.circle.other.domain.gateway.props.ActivitySourceGroupGateway;
import com.red.circle.other.infra.database.rds.dao.checkin.SignInDailyConfigDAO;
import com.red.circle.other.infra.database.rds.dao.checkin.UserSignInRecordDAO;
import com.red.circle.other.infra.database.rds.entity.SignInDailyConfig;
import com.red.circle.other.infra.database.rds.entity.UserSignInRecord;
import com.red.circle.other.inner.model.dto.activity.props.ActivityPropsGroup;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
public class SignInStatusQueryExe {

    private final SignInDailyConfigDAO dailyConfigDAO;
    private final UserSignInRecordDAO recordDAO;
    private final ActivitySourceGroupGateway activitySourceGroupGateway;

    public SignInStatusCO execute(Long userId) {
        LocalDate saudiToday = ZonedDateTimeAsiaRiyadhUtils.now().toLocalDate();
        LocalDate weekStartDate = saudiToday.with(DayOfWeek.MONDAY);
        int currentDayIndex = saudiToday.getDayOfWeek().getValue();

        List<SignInDailyConfig> configs = dailyConfigDAO.selectList(
                new LambdaQueryWrapper<SignInDailyConfig>()
                        .orderByAsc(SignInDailyConfig::getDayIndex)
        );

        List<UserSignInRecord> records = recordDAO.selectList(
                new LambdaQueryWrapper<UserSignInRecord>()
                        .eq(UserSignInRecord::getUserId, userId)
                        .eq(UserSignInRecord::getWeekStartDate, weekStartDate)
        );

        Set<Long> groupIdSet = configs.stream().map(SignInDailyConfig::getResourceGroupId).collect(Collectors.toSet());
        Map<Long, ActivityPropsGroup> propsGroupMap = activitySourceGroupGateway.mapActivityPropsGroup(SysOriginPlatformEnum.LIKEI.name(), groupIdSet);

        Map<Integer, UserSignInRecord> recordMap = records.stream()
                .collect(Collectors.toMap(UserSignInRecord::getDayIndex, r -> r));

        List<SignInDailyConfigCO> dailyConfigCOs = new ArrayList<>();
        List<Integer> signedDays = new ArrayList<>();

        for (SignInDailyConfig config : configs) {
            SignInDailyConfigCO co = new SignInDailyConfigCO();
            co.setDayIndex(config.getDayIndex());
            co.setIsPaid(config.getIsPaid() == 1);
            co.setPaidCost(config.getPaidCost());
            co.setLotteryTicketCount(config.getLotteryTicketCount());
            co.setAddActivityPropsGroup(propsGroupMap.get(config.getResourceGroupId()));

            UserSignInRecord record = recordMap.get(config.getDayIndex());
            if (record != null) {
                co.setIsSigned(true);
                co.setIsRewarded(record.getIsRewarded() == 1);
                co.setIsSupplement(record.getIsSupplement() == 1);
                signedDays.add(config.getDayIndex());
            } else {
                co.setIsSigned(false);
                co.setIsRewarded(false);
                co.setIsSupplement(false);
            }

            dailyConfigCOs.add(co);
        }

        SignInStatusCO statusCO = new SignInStatusCO();
        statusCO.setWeekStartDate(weekStartDate.toString());
        statusCO.setCurrentDayIndex(currentDayIndex);
        statusCO.setSignedDays(signedDays);
        statusCO.setDailyConfigs(dailyConfigCOs);

        return statusCO;
    }
}
