package com.yeejoin.amos.boot.module.elevator.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yeejoin.amos.boot.module.elevator.api.dto.AlertPlaceStatisticsDto;
import com.yeejoin.amos.boot.module.elevator.api.entity.AlertPlaceStatistics;
import com.yeejoin.amos.boot.module.elevator.api.mapper.AlertPlaceStatisticsMapper;
import com.yeejoin.amos.boot.module.elevator.api.service.IAlertPlaceStatisticsService;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 服务实现类
 *
 * @author system_generator
 * @date 2023-11-08
 */
@Service
public class AlertPlaceStatisticsServiceImpl extends BaseService<AlertPlaceStatisticsDto, AlertPlaceStatistics, AlertPlaceStatisticsMapper> implements IAlertPlaceStatisticsService {


    @Scheduled(cron = "0 0 0 1 * ?")
    @SchedulerLock(name = "AlertPlaceStatisticsServiceImpl", lockAtMostFor = "PT10M", lockAtLeastFor = "PT10M")
    public void statisticalGenerationTask(){
        statisticalGeneration(null);
    }

    @Override
    public void statisticalGeneration(String type) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        DecimalFormat decimalFormat = new DecimalFormat("0.00");
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        if (ObjectUtils.isEmpty(type)){
            cal.add(Calendar.MONTH, -1);
        }
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
        Date firstDayOfMonth = cal.getTime();
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date lastDayOfMonth = cal.getTime();
        ArrayList<AlertPlaceStatistics> list = new ArrayList<>();
        Map<String, Integer> totalMessage = this.baseMapper.getTotal(format.format(firstDayOfMonth) + " 00:00:00", format.format(lastDayOfMonth) + " 23:59:59");
        int trappedTotal = ObjectUtils.isEmpty(totalMessage.get("trappedNum")) ? 0 : Integer.parseInt(String.valueOf(totalMessage.get("trappedNum")));
        int faultTotal = ObjectUtils.isEmpty(totalMessage.get("faultNum")) ? 0 : Integer.parseInt(String.valueOf(totalMessage.get("faultNum")));
        List<Map<String, String>> allPlace = this.baseMapper.getAllPlace();
        AlertPlaceStatistics other = new AlertPlaceStatistics();
        other.setPlaceName("其他");
        other.setStartDate(format.format(firstDayOfMonth));
        other.setEndDate(format.format(lastDayOfMonth));
        other.setStatisticsDate(format.format(lastDayOfMonth).substring(0, 7));
        if (!ObjectUtils.isEmpty(allPlace)) {
            allPlace.forEach(item -> {
                if (!ObjectUtils.isEmpty(item.get("code")) && !ObjectUtils.isEmpty(item.get("name"))) {
                    AlertPlaceStatistics placeStatistics = this.baseMapper.getStatisticsMessage(item.get("code"), format.format(firstDayOfMonth) + " 00:00:00", format.format(lastDayOfMonth) + " 23:59:59");
                    placeStatistics.setPlaceName(item.get("name"));
                    placeStatistics.setStartDate(format.format(firstDayOfMonth));
                    placeStatistics.setEndDate(format.format(lastDayOfMonth));
                    placeStatistics.setStatisticsDate(format.format(lastDayOfMonth).substring(0, 7));
                    if (trappedTotal != 0 && !ObjectUtils.isEmpty(placeStatistics.getTrappedNum()) && placeStatistics.getTrappedNum() != 0) {
                        BigDecimal bigDecimal = new BigDecimal(placeStatistics.getTrappedNum());
                        BigDecimal bigDecimal1 = new BigDecimal(trappedTotal);
                        BigDecimal divide = bigDecimal.divide(bigDecimal1, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
                        placeStatistics.setTrappedRate(decimalFormat.format(divide) + "%");
                    } else {
                        placeStatistics.setTrappedRate("0%");
                    }
                    if (faultTotal != 0 && !ObjectUtils.isEmpty(placeStatistics.getFaultNum()) && placeStatistics.getFaultNum() != 0) {
                        BigDecimal bigDecimal = new BigDecimal(placeStatistics.getFaultNum());
                        BigDecimal bigDecimal1 = new BigDecimal(faultTotal);
                        BigDecimal divide = bigDecimal.divide(bigDecimal1, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
                        placeStatistics.setFaultRate(decimalFormat.format(divide) + "%");
                    } else {
                        placeStatistics.setFaultRate("0%");
                    }
                    other.setTrappedNum(ObjectUtils.isEmpty(other.getTrappedNum()) ? placeStatistics.getTrappedNum() : other.getTrappedNum() + placeStatistics.getTrappedNum());
                    other.setFaultNum(ObjectUtils.isEmpty(other.getFaultNum()) ? placeStatistics.getFaultNum() : other.getFaultNum() + placeStatistics.getFaultNum());
                    list.add(placeStatistics);
                }
            });
        }
        if (!ObjectUtils.isEmpty(other.getTrappedNum())) {
            other.setTrappedNum(trappedTotal - other.getTrappedNum());
        }
        if (!ObjectUtils.isEmpty(other.getFaultNum())) {
            other.setFaultNum(faultTotal - other.getFaultNum());
        }
        if (trappedTotal != 0 && !ObjectUtils.isEmpty(other.getTrappedNum()) && other.getTrappedNum() != 0) {
            BigDecimal bigDecimal = new BigDecimal(other.getTrappedNum());
            BigDecimal bigDecimal1 = new BigDecimal(trappedTotal);
            BigDecimal divide = bigDecimal.divide(bigDecimal1, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
            other.setTrappedRate(decimalFormat.format(divide) + "%");
        } else {
            other.setTrappedRate("0%");
        }
        if (faultTotal != 0 && !ObjectUtils.isEmpty(other.getFaultNum()) && other.getFaultNum() != 0) {
            BigDecimal bigDecimal = new BigDecimal(other.getFaultNum());
            BigDecimal bigDecimal1 = new BigDecimal(faultTotal);
            BigDecimal divide = bigDecimal.divide(bigDecimal1, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
            other.setFaultRate(decimalFormat.format(divide) + "%");
        } else {
            other.setFaultRate("0%");
        }
        list.add(other);
        if (!ObjectUtils.isEmpty(list)) {
            this.saveBatch(list);
        }
    }

    @Override
    public List<AlertPlaceStatistics> placeList(String date) {
        LambdaQueryWrapper<AlertPlaceStatistics> lambda = new QueryWrapper<AlertPlaceStatistics>().lambda();
        lambda.eq(AlertPlaceStatistics::getStatisticsDate, date);
        List<AlertPlaceStatistics> alertPlaceStatistics = this.baseMapper.selectList(lambda);
        AlertPlaceStatistics placeStatistics = new AlertPlaceStatistics();
        placeStatistics.setPlaceName("总 计");
        if (!ObjectUtils.isEmpty(alertPlaceStatistics)){
            alertPlaceStatistics.forEach(item ->{
                placeStatistics.setTrappedNum(ObjectUtils.isEmpty(placeStatistics.getTrappedNum()) ? item.getTrappedNum(): placeStatistics.getTrappedNum() + item.getTrappedNum());
                placeStatistics.setFaultNum(ObjectUtils.isEmpty(placeStatistics.getFaultNum()) ? item.getFaultNum(): placeStatistics.getFaultNum() + item.getFaultNum());
            });
            alertPlaceStatistics.add(placeStatistics);
        }
        return alertPlaceStatistics;
    }
}