package com.casic.missiles.service.Impl.meter;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.casic.missiles.dto.meter.MeterCertificateDto;
import com.casic.missiles.dto.ReturnDTO;
import com.casic.missiles.dto.ReturnUtil;
import com.casic.missiles.dto.meter.MeterStaffRequest;
import com.casic.missiles.dto.meter.MeterWorkbenchRequest;
import com.casic.missiles.dto.meter.MeterWorkbenchResponse;
import com.casic.missiles.enums.meter.ExamResultEnum;
import com.casic.missiles.enums.meter.MeterRoleTypeEnum;
import com.casic.missiles.mapper.meter.MeterCertificateMapper;
import com.casic.missiles.mapper.meter.MeterStaffMapper;
import com.casic.missiles.mapper.meter.MeterTrainPlanMapper;
import com.casic.missiles.mapper.meter.MeterTrainStaffMapper;
import com.casic.missiles.model.meter.MeterCertificate;
import com.casic.missiles.model.meter.MeterStaff;
import com.casic.missiles.model.meter.MeterTrainStaff;
import com.casic.missiles.modular.system.dao.RuRelationMapper;
import com.casic.missiles.modular.system.dao.UserMapper;
import com.casic.missiles.modular.system.model.RuRelation;
import com.casic.missiles.modular.system.model.User;
import com.casic.missiles.service.meter.MeterWorkbenchService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service("MeterWorkbenchService")
public class MeterWorkbenchServiceImpl implements MeterWorkbenchService {

    @Resource
    private MeterStaffMapper meterStaffMapper;

    @Resource
    private MeterCertificateMapper meterCertificateMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private RuRelationMapper ruRelationMapper;

    @Resource
    private MeterTrainPlanMapper trainPlanMapper;

    @Resource
    private MeterTrainStaffMapper meterTrainStaffMapper;



    @Override
    public ReturnDTO queryStaffCertificate(MeterWorkbenchRequest workbenchRequest) {
        List<MeterWorkbenchResponse> resList = new ArrayList<>();
        QueryWrapper<MeterStaff> staffWrapper = new QueryWrapper<>();
        QueryWrapper<MeterCertificate> certificateWrapper = new QueryWrapper<>();
        if(isMeterAdmin(workbenchRequest)){
            // 当前用户是计量部门负责人查询所有证书信息
            List<MeterCertificateDto> certificateList = meterCertificateMapper.queryCertificateList(new MeterStaffRequest());
            certificateList.forEach(bean->{
                MeterWorkbenchResponse certificateResponse = new MeterWorkbenchResponse();
                BeanUtils.copyProperties(bean, certificateResponse);
                certificateResponse.setMeterAdmin(true);
                resList.add(certificateResponse);
            });
        }else{
            // 当前用户不是计量部门负责人查询当前用户的证书信息
            // 通过登录账号获取计量人员信息
            staffWrapper.eq("account",workbenchRequest.getAccount());
            MeterStaff meterStaff = meterStaffMapper.selectOne(staffWrapper);
            if(null == meterStaff){
                log.error("该用户不是计量相关人员");
                return ReturnUtil.success(resList);
            }
            // 通过计量人员信息id对应证书
            certificateWrapper.eq("staff_id",meterStaff.getId());
            certificateWrapper.orderByAsc("create_time");
            List<MeterCertificate> certificateList = meterCertificateMapper.selectList(certificateWrapper);
            certificateList.forEach(bean->{
                MeterWorkbenchResponse certificateResponse = new MeterWorkbenchResponse();
                BeanUtils.copyProperties(bean, certificateResponse);
                certificateResponse.setMeterAdmin(false);
                // 判断证书过期时间于当前时间差多少天
                int days = (int) ((DateUtil.parseDate(bean.getValidDate()).getTime() - DateUtil.parseDate(DateUtil.formatDate(new Date())).getTime()) / (1000*3600*24));
                if(days>0){
                    certificateResponse.setLastValidDate(days);
                }
                resList.add(certificateResponse);
            });
        }
        return ReturnUtil.success(resList);
    }

    @Override
    public ReturnDTO meterStaffStatistic() {
        String endTime = DateUtil.format(new Date(),"yyyy-MM");
        String startTime = getStartTime();
        List<MeterWorkbenchResponse> resList = meterStaffMapper.meterStaffStatistic(startTime,endTime);
        if(resList.size()<12){
            List<String> monthList = getMonthList(12);
            resList.forEach(result->{
                monthList.remove(result.getDate());
            });
            for (String month : monthList) {
                MeterWorkbenchResponse result = new MeterWorkbenchResponse();
                result.setDate(month);
                result.setCount("0");
                resList.add(result);
            }
        }
        List<MeterWorkbenchResponse> newList = resList.stream().
                sorted(Comparator.comparing(MeterWorkbenchResponse::getDate)).
                collect(Collectors.toList());
        return ReturnUtil.success(newList);
    }

    @Override
    public ReturnDTO meterTrainStatistic() {
        String endTime = DateUtil.format(new Date(),"yyyy-MM");
        String startTime = getStartTime();
        List<MeterWorkbenchResponse>  resList = trainPlanMapper.meterTrainStatistic(startTime,endTime);
        if(resList.size()<12){
            List<String> monthList = getMonthList(12);
            resList.forEach(result->{
                monthList.remove(result.getDate());
            });
            for (String month : monthList) {
                MeterWorkbenchResponse result = new MeterWorkbenchResponse();
                result.setDate(month);
                result.setCount("0");
                resList.add(result);
            }
        }
        List<MeterWorkbenchResponse> newList = resList.stream().
                sorted(Comparator.comparing(MeterWorkbenchResponse::getDate)).
                collect(Collectors.toList());
        return ReturnUtil.success(newList);
    }

    @Override
    public ReturnDTO meterTrainLogStatistic(MeterWorkbenchRequest workbenchRequest) {
        MeterWorkbenchResponse result = new MeterWorkbenchResponse();
        if(isMeterAdmin(workbenchRequest)){
            // 当前用户是计量部门负责人查询总的培训考核信息
            QueryWrapper<MeterTrainStaff> trainLogWrapper = new QueryWrapper<>();
            // 查询考核总人次
            Long trainCount = meterTrainStaffMapper.selectCount(trainLogWrapper);
            result.setTrainCount(Math.toIntExact(trainCount));
            // 查询考核不合格人次
            trainLogWrapper.eq("exam_result", ExamResultEnum.NOT_QUALIFIED.getValue());
            Long notQualified = meterTrainStaffMapper.selectCount(trainLogWrapper);
            result.setNotQualified(Math.toIntExact(notQualified));
            // 合格人次=考核总人次-不合格人次
            result.setQualifiedCount(Math.toIntExact(trainCount - notQualified));
            result.setQualified(Math.toIntExact(trainCount - notQualified));
            result.setMeterAdmin(true);
        }else{
            // 当前用户是不是计量部门负责人查询该人员对应的的培训考核信息
            QueryWrapper<MeterStaff> staffWrapper = new QueryWrapper<>();
            // 通过登录账号获取计量人员信息
            staffWrapper.eq("account",workbenchRequest.getAccount());
            MeterStaff meterStaff = meterStaffMapper.selectOne(staffWrapper);
            if(null == meterStaff){
                log.error("该用户不是计量相关人员");
                result.setTrainCount(0);
                result.setQualifiedCount(0);
                result.setQualified(0);
                result.setNotQualified(0);
                return ReturnUtil.success(result);
            }
            QueryWrapper<MeterTrainStaff> trainLogWrapper = new QueryWrapper<>();
            int trainCount = Math.toIntExact(meterTrainStaffMapper.selectCount(trainLogWrapper));
            // 查询考核总人次
            result.setTrainCount(trainCount);
            // 查询考核不合格总人次
            trainLogWrapper.eq("exam_result", ExamResultEnum.NOT_QUALIFIED.getValue());
            // 合格总人次=考核总人次-考核不合格总人次
            result.setQualifiedCount(trainCount - Math.toIntExact(meterTrainStaffMapper.selectCount(trainLogWrapper)));
            QueryWrapper<MeterTrainStaff> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("staff_id", meterStaff.getId());
            // 查询当前用户考核次数
            int sum =  Math.toIntExact(meterTrainStaffMapper.selectCount(queryWrapper));
            // 查询当前用户未合格次数
            queryWrapper.eq("exam_result", ExamResultEnum.NOT_QUALIFIED.getValue());
            int notQualified = Math.toIntExact(meterTrainStaffMapper.selectCount(queryWrapper));
            result.setNotQualified(notQualified);
            // 当前用户合格=考核总次数-考核不合格次数
            result.setQualified(sum-notQualified);
            result.setMeterAdmin(false);
        }
        return ReturnUtil.success(result);
    }


    private boolean isMeterAdmin(MeterWorkbenchRequest workbenchRequest){
        QueryWrapper<User> userWrapper = new QueryWrapper<>();
        // 通过当前登录账号获取userId
        userWrapper.eq("account",workbenchRequest.getAccount());
        User user = userMapper.selectOne(userWrapper);
        // 通过userID和计量部门负责人角色id判断当前登录用户是否为负责人
        QueryWrapper<RuRelation> ruRelationWrapper = new QueryWrapper<>();
        ruRelationWrapper.eq("userid",user.getId());
        ruRelationWrapper.eq("roleid", MeterRoleTypeEnum.METER_DEPT_ADMIN.getCode());
        RuRelation ruRelation = ruRelationMapper.selectOne(ruRelationWrapper);
        return ObjectUtil.isNotEmpty(ruRelation);
    }

    public List<String> getMonthList(Integer count) {
        List<String> resList = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
            Date date = new Date();
            Calendar calendar = Calendar.getInstance();
            // 设置为当前时间
            calendar.setTime(date);
            calendar.add(Calendar.MONTH,-i);
            // 设置为上一个月
            date = calendar.getTime();
            String dateStr = format.format(date);
            resList.add(dateStr);
        }
        return resList;
    }
    public String getStartTime() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        // 设置为当前时间
        calendar.setTime(date);
        calendar.add(Calendar.MONTH,-12);
        date = calendar.getTime();
        return format.format(date);
    }
}
