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

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.casic.missiles.dto.business.board.*;
import com.casic.missiles.dto.cockpit.*;
import com.casic.missiles.enums.business.AgreementStatusEnum;
import com.casic.missiles.mapper.MeterFixedAssetsMapper;
import com.casic.missiles.mapper.business.BusinessOrderMapper;
import com.casic.missiles.mapper.business.BusinessOrderSampleRelationMapper;
import com.casic.missiles.mapper.equipment.EquipmentStandardEquipmentMapper;
import com.casic.missiles.mapper.finance.FinanceAgreementInfoMapper;
import com.casic.missiles.mapper.meter.MeterOrganizeMapper;
import com.casic.missiles.mapper.meter.MeterStaffMapper;
import com.casic.missiles.model.business.BusinessOrder;
import com.casic.missiles.model.equipment.EquipmentFixedAssets;
import com.casic.missiles.model.equipment.EquipmentStandardEquipment;
import com.casic.missiles.model.meter.MeterOrganize;
import com.casic.missiles.model.meter.MeterStaff;
import com.casic.missiles.service.business.IBusinessBoardService;
import com.casic.missiles.service.cockpit.IMeasureTaskService;
import com.casic.missiles.service.finance.IFinanceBusinessSettlementInfoService;
import com.casic.missiles.utils.ConvertUtils;
import com.casic.missiles.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Author: wangpeng
 * @Date: 2023/6/14 9:08
 */
@Service
public class MeasureTaskServiceImpl implements IMeasureTaskService {
    @Autowired
    private BusinessOrderMapper orderMapper;
    @Autowired
    private FinanceAgreementInfoMapper agreementInfoMapper;
    @Autowired
    private IFinanceBusinessSettlementInfoService settlementInfoService;
    @Autowired
    private EquipmentStandardEquipmentMapper standardEquipmentMapper;
    @Autowired
    private MeterFixedAssetsMapper fixedAssetsMapper;
    @Autowired
    private MeterOrganizeMapper organizeMapper;
    @Resource
    private MeterStaffMapper meterStaffMapper;
    @Autowired
    private IBusinessBoardService boardService;
    @Autowired
    private BusinessOrderSampleRelationMapper orderSampleRelationMapper;

    @Override
    public OrderInfoResponse orderInfo() {
        OrderInfoResponse response = new OrderInfoResponse();
        //查询已接收和检测完状态的委托单最早的日期、数量、成交额
        List<BusinessOrder> orders = orderMapper.selectOrderForCockpit();
        if(CollectionUtils.isEmpty(orders)){
            return response;
        }
        //本年签订收入合同总金额
        Integer agreementAmount = agreementInfoMapper.selectCompleteAmount(null, AgreementStatusEnum.ALREADY_COMPLETE);
        //本年业务结算总金额
        Integer settleAmount = settlementInfoService.selectCompleteAmount(null);
        Integer amount = agreementAmount + settleAmount;

        BusinessOrder businessOrder = orders.get(0);
        long subDay = DateUtils.subDaysByDateTime(businessOrder.getCreateTime(), DateUtil.now());
        response.setReceiveOrderDays(subDay);
        response.setReceiveOrderAmount(orders.size());
        response.setAmount(BigDecimal.valueOf(amount).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_HALF_UP).toPlainString());
        return response;
    }

    @Override
    public List<LabAssetsResponse> labAssets() {
        List<LabAssetsResponse> list = organizeMapper.selectStaffCount();
        list.forEach(response -> {
            QueryWrapper<EquipmentStandardEquipment> wrapper = new QueryWrapper<>();
            wrapper.eq("standard_laboratory", response.getDeptId());
            wrapper.eq("is_del", 0);
            response.setEquipmentCount(standardEquipmentMapper.selectCount(wrapper));
            QueryWrapper<EquipmentFixedAssets> assetsWrapper = new QueryWrapper<>();
            assetsWrapper.eq("use_dept", response.getDeptId());
            assetsWrapper.eq("asset_type", "1");
            assetsWrapper.eq("is_del", 0);
            response.setDeviceCount(fixedAssetsMapper.selectCount(assetsWrapper));
        });
        return list;
    }

    @Override
    public List<CockpitDeptOutputListResponse> deptOutputList(String startTime, String endTime) {
        BoardBaseRequest request = new BoardBaseRequest();
        request.setStartTime(startTime);
        request.setEndTime(endTime);
        BoardDeptOutputListResponse response = boardService.deptOutputList(request);
        List<BoardDeptOutputResponse> list = response.getList();
        if(CollectionUtils.isEmpty(list)){
            QueryWrapper<MeterOrganize> wrapper = new QueryWrapper<>();
            List<MeterOrganize> meterOrganizes = organizeMapper.selectList(wrapper);
            wrapper.eq("is_del", 0);
            wrapper.eq("is_lab", 1);
            List<CockpitDeptOutputListResponse> lists = new ArrayList<>();
            meterOrganizes.forEach(organize -> {
                CockpitDeptOutputListResponse cockpitDeptOutputListResponse = new CockpitDeptOutputListResponse();
                cockpitDeptOutputListResponse.setDeptId(organize.getDeptId());
                cockpitDeptOutputListResponse.setDeptName(organize.getOrganizeName());
                lists.add(cockpitDeptOutputListResponse);
            });
            return lists;
        }
        List<CockpitDeptOutputListResponse> outputDTOs = ConvertUtils.sourceToTarget(list, CockpitDeptOutputListResponse.class);
        List<CockpitDeptOutputListResponse> resultList = outputDTOs.stream().collect(Collectors.toMap(CockpitDeptOutputListResponse::getDeptId, a -> a, (o1, o2) -> {
            o1.setCertificates(o1.getCertificates() + o2.getCertificates());
            o1.setSamples(o1.getSamples() + o2.getSamples());
            o1.setOutPut(o1.getOutPut() + o2.getOutPut());
            return o1;
        })).values().stream().collect(Collectors.toList());
        return resultList;
    }

    @Override
    public DeptOutputRatioResponse deptOutputRatio() {
        //本月产值
        String thisMonthStartTime = DateUtils.getThisMonthFirst();
        List<CockpitDeptOutputListResponse> thisMonthResponses = this.deptOutputList(thisMonthStartTime, DateUtil.now());
        int thisMonthSum = thisMonthResponses.stream().mapToInt(CockpitDeptOutputListResponse::getOutPut).sum();
        String outPutYuan = BigDecimal.valueOf(thisMonthSum).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_HALF_UP).toPlainString();
        //上月产值
        String lastMonthStartTime = DateUtils.getLastMonthFirst();
        String lastMonthEndTime = DateUtils.getThisMonthFirst();
        List<CockpitDeptOutputListResponse> lastMonthResponses = this.deptOutputList(lastMonthStartTime, lastMonthEndTime);
        int lastMonthSum = lastMonthResponses.stream().mapToInt(CockpitDeptOutputListResponse::getOutPut).sum();
        //去年上月产值
        String lastYearThisMonthStartTime = DateUtils.getLastYearThisMonthFirst();
        String lastYearThisMonthEndTime = DateUtils.getLastYearThisMonthEnd();
        List<CockpitDeptOutputListResponse> lastYearResponses = this.deptOutputList(lastYearThisMonthStartTime, lastYearThisMonthEndTime);
        int lastYearSum = lastYearResponses.stream().mapToInt(CockpitDeptOutputListResponse::getOutPut).sum();

        BigDecimal thisMonthCount = BigDecimal.valueOf(Double.valueOf(thisMonthSum));
        //同比
        String sameRatio = "100.00%";
        if(0 != lastYearSum){
            BigDecimal lastYearCount = BigDecimal.valueOf(Double.valueOf(lastYearSum));
            BigDecimal sameRatioBigDecimal = thisMonthCount.subtract(lastYearCount).divide(lastYearCount, 2, BigDecimal.ROUND_HALF_UP);
            sameRatio = sameRatioBigDecimal.multiply(BigDecimal.valueOf(100)).toPlainString() + "%";
        }
        //环比
        String ringRatio = "100.00%";
        if(0 != lastMonthSum){
            BigDecimal lastMonthCount = BigDecimal.valueOf(Double.valueOf(lastMonthSum));
            BigDecimal ringRatioBigDecimal = thisMonthCount.subtract(lastMonthCount).divide(lastMonthCount, 2, BigDecimal.ROUND_HALF_UP);
            ringRatio = ringRatioBigDecimal.multiply(BigDecimal.valueOf(100)).toPlainString() + "%";
        }
        DeptOutputRatioResponse response = new DeptOutputRatioResponse();
        response.setOutPutYuan(outPutYuan);
        response.setSameRatio(sameRatio);
        response.setRingRatio(ringRatio);
        return response;
    }

    @Override
    public List<BoardDeptComprehensiveResponse> workList() {
        BoardDeptComprehensiveRequest request = new BoardDeptComprehensiveRequest();
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, 1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        Date m = c.getTime();
        String format = DateUtil.format(m, "yyyy-MM-dd HH:mm:ss");
        request.setStartTime(format);
        request.setEndTime(DateUtil.now());
        return boardService.deptComprehensive(request);
    }

    @Override
    public WorkRatioResponse workRatio() {
        //本月检完样品数，包括检测完成和待归还的，使用更新时间判断
        String now = DateUtil.now();
        WorkRatioResponse thisMonthResponse = orderSampleRelationMapper.selectCountByMonth(now);
        //上月
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, -1);
        Date m = c.getTime();
        String lastMonth = DateUtil.format(m, "yyyy-MM-dd HH:mm:ss");
        WorkRatioResponse lastMonthResponse = orderSampleRelationMapper.selectCountByMonth(lastMonth);
        //去年上月
        Calendar cc = Calendar.getInstance();
        cc.add(Calendar.YEAR, -1);
        Date y = cc.getTime();
        String lastYear = DateUtil.format(y, "yyyy-MM-dd HH:mm:ss");
        WorkRatioResponse lastYearResponse = orderSampleRelationMapper.selectCountByMonth(lastYear);

        BigDecimal thisMonthCount = BigDecimal.valueOf(Double.valueOf(thisMonthResponse.getMeasuredSampleCount()));
        //同比
        String sameRatio = "100.00%";
        if(0 != lastYearResponse.getMeasuredSampleCount()){
            BigDecimal lastYearCount = BigDecimal.valueOf(Double.valueOf(lastYearResponse.getMeasuredSampleCount()));
            BigDecimal sameRatioBigDecimal = thisMonthCount.subtract(lastYearCount).divide(lastYearCount, 2, BigDecimal.ROUND_HALF_UP);
            sameRatio = sameRatioBigDecimal.multiply(BigDecimal.valueOf(100)).toPlainString() + "%";
        }
        //环比
        String ringRatio = "100.00%";
        if(0 != lastMonthResponse.getMeasuredSampleCount()){
            BigDecimal lastMonthCount = BigDecimal.valueOf(Double.valueOf(lastMonthResponse.getMeasuredSampleCount()));
            BigDecimal ringRatioBigDecimal = thisMonthCount.subtract(lastMonthCount).divide(lastMonthCount, 2, BigDecimal.ROUND_HALF_UP);
            ringRatio = ringRatioBigDecimal.multiply(BigDecimal.valueOf(100)).toPlainString() + "%";
        }
        thisMonthResponse.setSameRatio(sameRatio);
        thisMonthResponse.setRingRatio(ringRatio);
        return thisMonthResponse;
    }

    @Override
    public OverdueSampleResponse overdueSample() {
        //超期样品数
        Integer sampleOverdueCount = orderSampleRelationMapper.selectCountForCockpit(4, "month");
        //本月样品数
        Integer sampleCount = orderSampleRelationMapper.selectCountForCockpit(0, "month");
        //超期仍检测中
        Integer overdueMeasureCount = orderSampleRelationMapper.selectCountForCockpit(1, "month");
        OverdueSampleResponse response = new OverdueSampleResponse();
        response.setSampleCount(sampleCount);
        response.setOverdueMeasureCount(overdueMeasureCount);
        response.setSampleOverdueCount(sampleOverdueCount);
        return response;
    }

    @Override
    public List<StaffAnalyseListResponse> staffAnalyse() {
        BoardBaseRequest request = new BoardBaseRequest();
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, 1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        Date m = c.getTime();
        String format = DateUtil.format(m, "yyyy-MM-dd HH:mm:ss");
        request.setStartTime(format);
        request.setEndTime(DateUtil.now());
        BoardDeptOutputListResponse response = boardService.deptOutputList(request);
        List<BoardDeptOutputResponse> list = response.getList();

        QueryWrapper<MeterStaff> wrapper = new QueryWrapper<>();
        wrapper.eq("is_del", 0);
        List<MeterStaff> meterStaffs = meterStaffMapper.selectList(wrapper);
        if(CollectionUtils.isEmpty(list)){
            List<StaffAnalyseListResponse> lists = new ArrayList<>();
            meterStaffs.forEach(staff -> {
                StaffAnalyseListResponse staffAnalyseListResponse = new StaffAnalyseListResponse();
                staffAnalyseListResponse.setStaffId(staff.getId());
                staffAnalyseListResponse.setStaffName(staff.getName());
                lists.add(staffAnalyseListResponse);
            });
            return lists;
        }
        List<StaffAnalyseListResponse> resultList = ConvertUtils.sourceToTarget(list, StaffAnalyseListResponse.class);
        List<Long> collect = resultList.stream().map(StaffAnalyseListResponse::getStaffId).collect(Collectors.toList());
        meterStaffs.forEach(staff -> {
            if(!collect.contains(staff.getId())){
                StaffAnalyseListResponse dto = new StaffAnalyseListResponse();
                dto.setStaffId(staff.getId());
                dto.setStaffName(staff.getName());
                resultList.add(dto);
            }
        });
        return resultList;
    }
}
