package com.red.circle.other.infra.database.rds.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.red.circle.other.infra.database.rds.dao.task.RoomDailyTaskClaimRecordDAO;
import com.red.circle.other.infra.database.rds.dao.task.RoomDailyTaskConfigDAO;
import com.red.circle.other.infra.database.rds.dao.task.RoomDailyTaskProgressDAO;
import com.red.circle.other.infra.database.rds.dao.task.RoomDailyTaskTierDAO;
import com.red.circle.other.infra.database.rds.entity.task.RoomDailyTaskClaimRecord;
import com.red.circle.other.infra.database.rds.entity.task.RoomDailyTaskConfig;
import com.red.circle.other.infra.database.rds.entity.task.RoomDailyTaskProgress;
import com.red.circle.other.infra.database.rds.entity.task.RoomDailyTaskTier;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.List;

@Service
@RequiredArgsConstructor
public class RoomDailyTaskDatabaseService {

    private final RoomDailyTaskConfigDAO configDAO;
    private final RoomDailyTaskTierDAO tierDAO;
    private final RoomDailyTaskProgressDAO progressDAO;
    private final RoomDailyTaskClaimRecordDAO claimRecordDAO;

    public List<RoomDailyTaskConfig> listEnabledConfigs(Integer taskCategory) {
        return configDAO.selectList(
                new LambdaQueryWrapper<RoomDailyTaskConfig>()
                        .eq(RoomDailyTaskConfig::getStatus, 1)
                        .eq(RoomDailyTaskConfig::getTaskCategory, taskCategory)
                        .orderByAsc(RoomDailyTaskConfig::getSortOrder)
        );
    }

    public List<RoomDailyTaskTier> listTiersByTaskCodes(List<String> taskCodes) {
        return tierDAO.selectList(
                new LambdaQueryWrapper<RoomDailyTaskTier>()
                        .in(RoomDailyTaskTier::getTaskCode, taskCodes)
                        .orderByAsc(RoomDailyTaskTier::getTierIndex)
        );
    }

    public List<RoomDailyTaskProgress> listProgressByUser(Long userId, LocalDate cycleDate) {
        return progressDAO.selectList(
                new LambdaQueryWrapper<RoomDailyTaskProgress>()
                        .eq(RoomDailyTaskProgress::getUserId, userId)
                        .eq(RoomDailyTaskProgress::getCycleDate, cycleDate)
        );
    }

    public RoomDailyTaskProgress getProgress(Long userId, String taskCode, LocalDate cycleDate) {
        return progressDAO.selectList(
                new LambdaQueryWrapper<RoomDailyTaskProgress>()
                        .eq(RoomDailyTaskProgress::getUserId, userId)
                        .eq(RoomDailyTaskProgress::getTaskCode, taskCode)
                        .eq(RoomDailyTaskProgress::getCycleDate, cycleDate)
                        .last("limit 1")
        ).stream().findFirst().orElse(null);
    }

    public void saveOrUpdateProgress(RoomDailyTaskProgress progress) {
        if (progress.getId() == null) {
            progressDAO.insert(progress);
        } else {
            progressDAO.updateById(progress);
        }
    }

    public boolean existsClaimRecord(String bizNo) {
        return claimRecordDAO.selectCount(
                new LambdaQueryWrapper<RoomDailyTaskClaimRecord>()
                        .eq(RoomDailyTaskClaimRecord::getBizNo, bizNo)
        ) > 0;
    }

    public void saveClaimRecord(RoomDailyTaskClaimRecord record) {
        claimRecordDAO.insert(record);
    }

    public void saveClaimRecords(List<RoomDailyTaskClaimRecord> records) {
        claimRecordDAO.insertBatchSomeColumn(records);
    }

    public RoomDailyTaskConfig getConfigByCode(String taskCode) {
        return configDAO.selectList(
                new LambdaQueryWrapper<RoomDailyTaskConfig>()
                        .eq(RoomDailyTaskConfig::getTaskCode, taskCode)
                        .eq(RoomDailyTaskConfig::getStatus, 1)
                        .last("limit 1")
        ).stream().findFirst().orElse(null);
    }

    public RoomDailyTaskTier getTier(String taskCode, Integer tierIndex) {
        return tierDAO.selectList(
                new LambdaQueryWrapper<RoomDailyTaskTier>()
                        .eq(RoomDailyTaskTier::getTaskCode, taskCode)
                        .eq(RoomDailyTaskTier::getTierIndex, tierIndex)
                        .last("limit 1")
        ).stream().findFirst().orElse(null);
    }
}
