package com.sonic.frog.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.sonic.frog.dao.SignInStatDao;
import com.sonic.frog.domain.entity.SignInRecord;
import com.sonic.frog.domain.entity.SignInStat;
import com.sonic.frog.domain.output.SignInListOutput;
import com.sonic.frog.domain.output.SignInRoundOutput;
import com.sonic.frog.enums.SignInCoinNumEnum;
import com.sonic.frog.service.SignInRecordService;
import com.sonic.frog.service.SignInStatSearchService;
import com.sonic.frog.service.SignInStatService;
import com.sonic.frog.utils.DateConvertUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author zzhan
 * @Description 签到统计数据表查询
 * @Date 2024/6/11 11:13
 * @Version 1.0
 */
@Slf4j
@Service
public class SignInStatSearchServiceImpl implements SignInStatSearchService {

    @Autowired
    private SignInStatDao signInStatDao;
    @Autowired
    private SignInStatService signInStatService;
    @Autowired
    private SignInRecordService signInRecordService;

    @Override
    public SignInRoundOutput signInList(Long currentUserId) {
        SignInRoundOutput output = new SignInRoundOutput();
        //获取并初始化签到周期数据
        SignInStat signInStat = getAndInitSignInStat(currentUserId);
        //查询签到明细数据
        List<SignInRecord> list = signInRecordService.list(Wrappers.<SignInRecord>lambdaQuery()
                .select(SignInRecord::getDayStr)
                .eq(SignInRecord::getUserId, currentUserId));
        Map<String, SignInRecord> recordMap = list.stream().collect(Collectors.toMap(e -> e.getDayStr(), Function.identity()));
        //获取时间周期内的所有日期
        List<String> dayStrList = DateConvertUtils.getDateStringsBetween(signInStat.getStartDay(), signInStat.getEndDay());
        List<SignInListOutput> outputList = Lists.newArrayList();
        int dayNum = 0;
        //循环日期 组装完整的7天签到列表数据返回给前端
        for (String dayStr : dayStrList) {
            dayNum = dayNum + 1;
            //获取coinNum
            SignInListOutput signInListOutput = new SignInListOutput();
            signInListOutput.setDayStr(dayStr);
            SignInRecord signInRecord = recordMap.get(dayStr);
            signInListOutput.setSignIn(signInRecord != null);
            signInListOutput.setCoinNum(SignInCoinNumEnum.getCoinNum(dayNum));
            outputList.add(signInListOutput);
        }
        output.setList(outputList);
        //返回最大连续签到天数
        output.setContinuousDays(signInStat.getAllDays());
        return output;
    }

    /**
     * 获取并初始化签到周期数据
     * @param currentUserId
     * @return
     */
    private SignInStat getAndInitSignInStat(Long currentUserId) {
        SignInStat signInStat = signInStatService.getOne(Wrappers.<SignInStat>lambdaQuery()
                .eq(SignInStat::getUserId, currentUserId)
                .orderByDesc(SignInStat::getId)
                .last("limit 1"));
        //今天的日期
        String todayStr = DateConvertUtils.formatYearMonthDay(DateConvertUtils.getDateLaTime());
        boolean queryDataBl =  false;
        //判断当前时间是否已超过周期
        if(signInStat == null || !DateConvertUtils.currentDayInRangeDayCheck(todayStr, signInStat.getStartDay(), signInStat.getEndDay())) {
            //初始化签到周期数据
            if(signInStat == null) {
                signInStatService.init(currentUserId);
            } else {
                //更新数据
                signInStat.setStartDay(DateConvertUtils.formatYearMonthDay(DateConvertUtils.getDateLaTime()));
                signInStat.setEndDay(DateConvertUtils.formatYearMonthDay(DateConvertUtils.getDateLaTime().plusDays(6)));
                //重新初始化周期，今天为开始日期
                signInStatService.updateStartEndDayAndDays(signInStat.getId(), signInStat.getStartDay(), signInStat.getEndDay());
            }
            //需要重新查询数据
            queryDataBl = true;
        } else {
            //获取系统当前时间
            LocalDateTime pstNowTime = DateConvertUtils.getDateLaTime();
            //如果今天是第一天开始时间则不用判断昨天是否签到，否则需要进行判断
            if(DateConvertUtils.convertStringToDateTime(signInStat.getStartDay()).isBefore(pstNowTime.minusDays(1))) {
                //昨天漏了一天的情况，今天的话是不算的，所以需要查询昨天的签到数据是否存在
                SignInRecord yesterdaySignInRecord = signInRecordService.getOne(Wrappers.<SignInRecord>lambdaQuery()
                        .select(SignInRecord::getId, SignInRecord::getDayStr)
                        .eq(SignInRecord::getUserId, currentUserId)
                        .eq(SignInRecord::getDayStr, DateConvertUtils.formatYearMonthDay(pstNowTime.minusDays(1))));
                if(yesterdaySignInRecord == null) {
                    //重新初始化数据
                    signInStat.setStartDay(DateConvertUtils.formatYearMonthDay(DateConvertUtils.getDateLaTime()));
                    signInStat.setEndDay(DateConvertUtils.formatYearMonthDay(DateConvertUtils.getDateLaTime().plusDays(6)));
                    //重新初始化周期，今天为开始日期
                    signInStatService.updateStartEndDayAndDays(signInStat.getId(), signInStat.getStartDay(), signInStat.getEndDay());
                    //需要重新查询数据
                    queryDataBl = true;
                }
            }
        }
        if(queryDataBl) {
            //初始化完了后重新查询一下数据
            signInStat = signInStatService.getOne(Wrappers.<SignInStat>lambdaQuery()
                    .eq(SignInStat::getUserId, currentUserId)
                    .orderByDesc(SignInStat::getId)
                    .last("limit 1"));
        }
        return signInStat;
    }

}
