package com.gci.boot.modules.vehicles.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gci.boot.constant.CommonConstant;
import com.gci.boot.modules.vehicles.entity.TbAccidentInfo;
import com.gci.boot.modules.vehicles.entity.TbAnnualInspectionInfo;
import com.gci.boot.modules.vehicles.entity.TbAnnualInspectionRemind;
import com.gci.boot.modules.vehicles.entity.TbViolationRecord;
import com.gci.boot.modules.vehicles.mapper.TbAccidentInfoMapper;
import com.gci.boot.modules.vehicles.mapper.TbAnnualInspectionRemindMapper;
import com.gci.boot.modules.vehicles.service.ITbAnnualInspectionInfoService;
import com.gci.boot.modules.vehicles.service.ITbAnnualInspectionRemindService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gci.boot.modules.vehicles.service.ITbViolationRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 年检提醒 服务实现类
 * </p>
 *
 * @author 2464
 * @since 2023-11-16
 */
@Service
public class TbAnnualInspectionRemindServiceImpl extends ServiceImpl<TbAnnualInspectionRemindMapper, TbAnnualInspectionRemind> implements ITbAnnualInspectionRemindService {

    @Resource
    private TbAnnualInspectionRemindMapper annualInspectionRemindMapper;
    @Resource
    private ITbViolationRecordService violationRecordService;
    @Resource
    private TbAccidentInfoMapper accidentInfoMapper;
    @Autowired
    @Lazy
    private ITbAnnualInspectionInfoService annualInspectionInfoService;

    @Override
    public void recalculate(String plateNumber) {
        LambdaQueryWrapper<TbAnnualInspectionRemind> eq = new LambdaQueryWrapper<TbAnnualInspectionRemind>().eq(TbAnnualInspectionRemind::getPlateNumber, plateNumber);
        List<TbAnnualInspectionRemind> list = list(eq);

        List<TbAnnualInspectionRemind> needUpdate = new ArrayList<>();
        if (list.size() > 0) {
            //有效期倒序
            list.sort(Comparator.comparing(TbAnnualInspectionRemind::getValidityPeriod).reversed());
            boolean target = false;
            DateTime dateTime = DateUtil.beginOfDay(new DateTime());
            if (list.size() == 0) {
                return;
            }
            for (int i = 0; i < list.size(); i++) {
                TbAnnualInspectionRemind annualInspectionRemind = list.get(i);
                int between = Convert.toInt(DateUtil.between(annualInspectionRemind.getValidityPeriod(), dateTime, DateUnit.DAY, false));
                String remindStatus = annualInspectionRemind.getRemindStatus();
                String overdueType = annualInspectionRemind.getOverdueType();


                if (i == 0) {
                    //已过期
                    if ("0".equals(remindStatus)) {
                        //改为提醒中
                        annualInspectionRemind.setRemindStatus("1");
                    }
                    if (between > 0) {
                        annualInspectionRemind.setDaysToOverdue(0);
                        annualInspectionRemind.setOverdueDays(between);
                        annualInspectionRemind.setOverdueType("2");
                        annualInspectionRemind.setRemindStatus("1");
                    } else if (between < 0) {
                        annualInspectionRemind.setDaysToOverdue(-between);
                        annualInspectionRemind.setOverdueDays(0);
                        annualInspectionRemind.setOverdueType("1");
                        annualInspectionRemind.setRemindStatus("1");
                    } else {
                        annualInspectionRemind.setDaysToOverdue(0);
                        annualInspectionRemind.setOverdueDays(0);
                        annualInspectionRemind.setOverdueType("1");
                        annualInspectionRemind.setRemindStatus("1");
                    }
                    target = true;
                    needUpdate.add(annualInspectionRemind);
                } else {
                    if (target) {
                        //其他数据提醒中改为已过期
                        if ("1".equals(remindStatus)) {
                            annualInspectionRemind.setRemindStatus("0");
                            needUpdate.add(annualInspectionRemind);
                        }
                    }
                }
            }
            if (needUpdate.size() > 0) {
                updateBatchById(needUpdate);
            }
        }
    }

    @Override
    public IPage<TbAnnualInspectionRemind> pageBuild(Page<TbAnnualInspectionRemind> page, LambdaQueryWrapper<TbAnnualInspectionRemind> lambdaQueryWrapper) {
        lambdaQueryWrapper.eq(TbAnnualInspectionRemind::getDelFlag,CommonConstant.DEL_FLAG_0)
                .le(TbAnnualInspectionRemind::getDaysToOverdue,60);
        IPage<TbAnnualInspectionRemind> annualInspectionRemindIPage = annualInspectionRemindMapper.pageBuild(page,lambdaQueryWrapper);
        for (TbAnnualInspectionRemind record : annualInspectionRemindIPage.getRecords()) {
            int violationCount = violationRecordService.count(new LambdaQueryWrapper<TbViolationRecord>().eq(TbViolationRecord::getPlateNumber, record.getPlateNumber()).eq(TbViolationRecord::getHandleResult, 0));
            record.setViolationCount(violationCount);
            Integer integer = accidentInfoMapper.countAccidentNotClose(new QueryWrapper<TbAccidentInfo>().eq("tai.plate_number", record.getPlateNumber()).and(i -> i.eq("tap.case_closed", CommonConstant.NO)
                    .or().isNull("tap.case_closed")));
            record.setAccidentCount(integer);
        }
        return annualInspectionRemindIPage;
    }

    @Override
    public void updateDate() {
        DateTime dateTime = DateUtil.beginOfDay(new DateTime());
        LambdaQueryWrapper<TbAnnualInspectionRemind> eq = new LambdaQueryWrapper<TbAnnualInspectionRemind>().eq(TbAnnualInspectionRemind::getRemindStatus, '1');
        List<TbAnnualInspectionRemind> list = list(eq);
        for (TbAnnualInspectionRemind annualInspectionRemind : list) {
            int between = Convert.toInt(DateUtil.between(annualInspectionRemind.getValidityPeriod(), dateTime, DateUnit.DAY, false));
            if (between > 0) {
                annualInspectionRemind.setDaysToOverdue(0);
                annualInspectionRemind.setOverdueDays(between);
                annualInspectionRemind.setOverdueType("2");
                annualInspectionRemind.setRemindStatus("1");
            } else if (between < 0) {
                annualInspectionRemind.setDaysToOverdue(-between);
                annualInspectionRemind.setOverdueDays(0);
                annualInspectionRemind.setOverdueType("1");
                annualInspectionRemind.setRemindStatus("1");
            } else {
                annualInspectionRemind.setDaysToOverdue(0);
                annualInspectionRemind.setOverdueDays(0);
                annualInspectionRemind.setOverdueType("1");
                annualInspectionRemind.setRemindStatus("1");
            }
        }
        updateBatchById(list);
    }

    @Override
    public void init() {
        List<TbAnnualInspectionInfo> list = annualInspectionInfoService.list();

        List<TbAnnualInspectionRemind> inspectionReminds = list();
        List<String> collect = inspectionReminds.stream().map(TbAnnualInspectionRemind::getInfoId).collect(Collectors.toList());
        List<TbAnnualInspectionRemind> needAdd = new ArrayList<TbAnnualInspectionRemind>();

        List<TbAnnualInspectionInfo> annualInspectionInfoList = list.stream().filter(i -> !collect.contains(i.getId())).collect(Collectors.toList());

        for (TbAnnualInspectionInfo annualInspectionInfo : annualInspectionInfoList) {
            TbAnnualInspectionRemind annualInspectionRemind = buildRemind(annualInspectionInfo);
            needAdd.add(annualInspectionRemind);
        }
        saveBatch(needAdd);
        List<String> collect1 = needAdd.stream().map(TbAnnualInspectionRemind::getPlateNumber).distinct().collect(Collectors.toList());
        for (String s : collect1) {
            recalculate(s);
        }

    }


    @Override
    public TbAnnualInspectionRemind buildRemind(TbAnnualInspectionInfo tbAnnualInspectionInfo) {
        DateTime dateTime = DateUtil.beginOfDay(new DateTime());
        long between = DateUtil.between(tbAnnualInspectionInfo.getValidityPeriod(), dateTime, DateUnit.DAY,false);

        TbAnnualInspectionRemind annualInspectionRemind = new TbAnnualInspectionRemind();
        BeanUtil.copyProperties(tbAnnualInspectionInfo,annualInspectionRemind);
        annualInspectionRemind.setInfoId(annualInspectionRemind.getId());
        annualInspectionRemind.setId(null);
        if (between > 0) {
            annualInspectionRemind.setDaysToOverdue(0);
            annualInspectionRemind.setOverdueDays(Convert.toInt(between));
            annualInspectionRemind.setOverdueType("1");
            annualInspectionRemind.setRemindStatus("1");
        } else if (between < 0) {
            annualInspectionRemind.setDaysToOverdue(Convert.toInt(-between));
            annualInspectionRemind.setOverdueDays(0);
            annualInspectionRemind.setOverdueType("2");
            annualInspectionRemind.setRemindStatus("1");
        } else {
            annualInspectionRemind.setDaysToOverdue(0);
            annualInspectionRemind.setOverdueDays(0);
            annualInspectionRemind.setOverdueType("1");
            annualInspectionRemind.setRemindStatus("1");
        }
        return annualInspectionRemind;

    }

    @Override
    public TbAnnualInspectionRemind findRemind(TbAnnualInspectionInfo tbAnnualInspectionInfo) {
        LambdaQueryWrapper<TbAnnualInspectionRemind> eq = new LambdaQueryWrapper<TbAnnualInspectionRemind>().eq(TbAnnualInspectionRemind::getInfoId, tbAnnualInspectionInfo.getId()).last("limit 1");
        TbAnnualInspectionRemind annualInspectionRemind = getOne(eq);
        if (BeanUtil.isNotEmpty(annualInspectionRemind)) {
            annualInspectionRemind.setPlateNumber(tbAnnualInspectionInfo.getPlateNumber());
            annualInspectionRemind.setValidityPeriod(tbAnnualInspectionInfo.getValidityPeriod());
            DateTime dateTime = DateUtil.beginOfDay(new DateTime());
            long between = DateUtil.between(tbAnnualInspectionInfo.getValidityPeriod(), dateTime, DateUnit.DAY,false);
            if (between > 0) {
                annualInspectionRemind.setDaysToOverdue(0);
                annualInspectionRemind.setOverdueDays(Convert.toInt(between));
                annualInspectionRemind.setOverdueType("1");
                annualInspectionRemind.setRemindStatus("1");
            } else if (between < 0) {
                annualInspectionRemind.setDaysToOverdue(Convert.toInt(-between));
                annualInspectionRemind.setOverdueDays(0);
                annualInspectionRemind.setOverdueType("2");
                annualInspectionRemind.setRemindStatus("1");
            } else {
                annualInspectionRemind.setDaysToOverdue(0);
                annualInspectionRemind.setOverdueDays(0);
                annualInspectionRemind.setOverdueType("1");
                annualInspectionRemind.setRemindStatus("1");
            }
            return annualInspectionRemind;
        } else {
            return null;
        }
    }
}
