package com.mosty.base.manager.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mosty.base.manager.mapper.TbJcglKhbmMapper;
import com.mosty.base.manager.mapper.TbJcglKhtjMapper;
import com.mosty.base.manager.remote.TbBaseAdaptRemoteService;
import com.mosty.base.manager.remote.TbHczxAdaptRemoteService;
import com.mosty.base.manager.remote.TbQwzxAdaptRemoteService;
import com.mosty.base.manager.remote.TbYjzlAdaptRrmoteService;
import com.mosty.base.manager.service.TbJcglKhtjService;
import com.mosty.base.model.entity.jcgl.TbJcglKhbm;
import com.mosty.base.model.entity.jcgl.TbJcglKhtj;
import com.mosty.base.model.query.jcgl.TbJcglKhtjQuery;
import com.mosty.base.model.query.jcgl.TbJcglKhtjStatisticsQuery;
import com.mosty.base.model.vo.base.DeptInfoVo;
import com.mosty.base.model.vo.jcgl.TbJcglKhtjVo;
import com.mosty.base.utils.DateUtils;
import com.mosty.common.base.exception.BusinessException;
import com.mosty.common.token.UserInfo;
import com.mosty.common.token.UserInfoManager;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

@Service
@AllArgsConstructor
public class TbJcglKhtjServiceImpl extends ServiceImpl<TbJcglKhtjMapper, TbJcglKhtj>
        implements TbJcglKhtjService {

    private final TbJcglKhbmMapper tbJcglKhbmMapper;
    private final TbQwzxAdaptRemoteService tbQwzxAdaptRemoteService;
    private final TbYjzlAdaptRrmoteService tbYjzlAdaptRrmoteService;
    private final TbBaseAdaptRemoteService tbBaseAdaptRemoteService;
    private final TbHczxAdaptRemoteService tbHczxAdaptRemoteService;

    @Override
    public void builder(String time) {
        if (StringUtils.isEmpty(time)) throw new BusinessException("请输入统计日期！");
        List<TbJcglKhbm> bmList = this.tbJcglKhbmMapper.selectList(
                new LambdaQueryWrapper<TbJcglKhbm>()
                        .eq(TbJcglKhbm::getXtSjzt, "1")
        );
        if (!CollectionUtils.isEmpty(bmList)) {
            bmList.forEach(item -> {
                TbJcglKhtj tj = this.baseMapper.selectOne(
                        new LambdaQueryWrapper<TbJcglKhtj>()
                                .eq(TbJcglKhtj::getSsbmdm, item.getSsbmdm())
                                .eq(TbJcglKhtj::getTjrq, time)
                );
                if (tj == null) {
                    tj = new TbJcglKhtj();
                }
                tj.setTjrq(DateUtils.strToDate(time, "01"));
                tj.setTjsj(DateUtils.strToDate(time + " " + DateUtils.getQueryDateString(new Date(), "10"), "02"));

                String ssbm = this.tbBaseAdaptRemoteService.getSsbm(item.getSsbmdm(), null);

                tj.setYbb(item.getYbb());
                tj.setZsbb(item.getZsbb());
                tj.setSjbb(this.getSjbb(ssbm, time));
                //规则修改 通过最少报备来计算
                tj.setWbb(Math.max((tj.getZsbb() - tj.getSjbb()), 0));
                tj.setBbkf(tj.getSjbb() >= item.getZsbb() ? new BigDecimal(0) : item.getBbkf());
                tj.setBbf(new BigDecimal(item.getBbf().doubleValue() - tj.getBbkf().doubleValue()));


                tj.setYqs(this.getYqs(ssbm, time));
                tj.setZsqs(item.getZsqs());
                tj.setSjqs(this.getSjqs(ssbm, time));
                tj.setWqs(Math.max((tj.getZsqs() - tj.getSjqs()), 0));
                tj.setQskf(tj.getSjqs() >= item.getZsqs() ? new BigDecimal(0) : item.getQskf());
                tj.setQsf(new BigDecimal(item.getQsf().doubleValue() - tj.getQskf().doubleValue()));

                tj.setYxl(this.getYxl(ssbm, time));
                //最少巡逻 80%
                tj.setZsxl((int) Math.ceil(tj.getYxl() * 0.8));
                tj.setSjxl(this.getSjxl(ssbm, time));
                tj.setWxl(Math.max((tj.getZsxl() - tj.getSjxl()), 0));
                tj.setXlkf(tj.getSjxl() >= tj.getZsxl() ? new BigDecimal(0) : item.getXlkf());
                tj.setXlf(new BigDecimal(item.getXlf().doubleValue() - tj.getXlkf().doubleValue()));


                tj.setYcr(item.getYcr());
                tj.setZscr(item.getZscr());
                tj.setSjcr(this.getsjpcr(ssbm, time));
                tj.setWcr(Math.max((tj.getZscr() - tj.getSjcr()), 0));
                tj.setCrkf(tj.getSjcr() >= item.getZscr() ? new BigDecimal(0) : item.getCrkf());
                tj.setCrf(new BigDecimal(item.getCrf().doubleValue() - tj.getCrkf().doubleValue()));


                tj.setYcc(item.getYcc());
                tj.setZscc(item.getZscc());
                tj.setSjcc(this.getsjpcc(ssbm, time));
                tj.setWcc(Math.max((tj.getZscc() - tj.getSjcc()), 0));
                tj.setCckf(tj.getSjcc() >= item.getZscc() ? new BigDecimal(0) : item.getCckf());
                tj.setCcf(new BigDecimal(item.getCcf().doubleValue() - tj.getCckf().doubleValue()));


                Map<String, Integer> scLc = this.getScLc(ssbm, time);

                tj.setYxllc(item.getYxllc());
                tj.setZsxllc(item.getZsxllc());
                tj.setSjxllc(scLc.get("xflc"));
                tj.setWxllc(Math.max((tj.getZsxllc() - tj.getSjxllc()), 0));
                tj.setXllckf(tj.getSjxllc() >= item.getZsxllc() ? new BigDecimal(0) : item.getXllckf());
                tj.setXllcf(new BigDecimal(item.getXllcf().doubleValue() - tj.getXllckf().doubleValue()));


                tj.setYxlsc(item.getYxlsc());
                tj.setZsxlsc(item.getZsxlsc());
                tj.setSjxlsc(scLc.get("xfsc"));
                tj.setWxlsc(Math.max((tj.getZsxlsc() - tj.getSjxlsc()), 0));
                tj.setXlsckf(tj.getSjxlsc() >= item.getZsxlsc() ? new BigDecimal(0) : item.getXlsckf());
                tj.setXlscf(new BigDecimal(item.getXlscf().doubleValue() - tj.getXlsckf().doubleValue()));


                tj.setYcw(item.getYcw());
                tj.setZscw(item.getZscw());
                tj.setSjcw(this.getPcWptj(ssbm, time));
                tj.setWcw(Math.max((tj.getZscw() - tj.getSjcw()), 0));
                tj.setCwkf(tj.getSjcw() >= item.getZscw() ? new BigDecimal(0) : item.getCwkf());
                tj.setCwf(new BigDecimal(item.getCwf().doubleValue() - tj.getCwkf().doubleValue()));


                //计算三项扣分 得分
                if ((ObjectUtils.isNotEmpty(tj.getXlkf()) && tj.getXlkf().compareTo(BigDecimal.ZERO) > 0)
                        || (ObjectUtils.isNotEmpty(tj.getXlsckf()) && tj.getXlsckf().compareTo(BigDecimal.ZERO) > 0)
                        || (ObjectUtils.isNotEmpty(tj.getXllckf()) && tj.getXllckf().compareTo(BigDecimal.ZERO) > 0)
                ) {
                    tj.setSxkf(new BigDecimal(0.15));
                }else{
                    tj.setSxkf(new BigDecimal(0));
                }
                tj.setSsbm(item.getSsbm());
                tj.setSsbmdm(item.getSsbmdm());
                tj.setSsxgaj(item.getSsxgaj());
                tj.setSsxgajdm(item.getSsxgajdm());
                tj.setSssgaj(item.getSssgaj());
                tj.setSssgajdm(item.getSssgajdm());
                tj.setSsbmid(item.getSsbmid());
                tj.setSsxgajid(item.getSsxgajid());
                tj.setSssgajid(item.getSssgajid());
                tj.setXtSjly("1");

                if (StringUtils.isEmpty(tj.getId())) {
                    this.baseMapper.insert(tj);
                } else {
                    this.baseMapper.updateById(tj);
                }


            });
        }
    }

    public double jsfz(int wx, double zf, double kf) {
        if (wx < 1) return zf;
        double kfs = zf - (kf * wx);
        return kfs < 0 ? 0 : kfs;
    }

    @Override
    public List<TbJcglKhtj> getList(TbJcglKhtjQuery dto) {
        Map<String, String> map = this.analysisTime(dto);
        String kssj = map.get("kssj");
        String jssj = map.get("jssj");
        if (StringUtils.isEmpty(kssj) || StringUtils.isEmpty(jssj))
            throw new BusinessException("时间查询参数异常！！");
        dto.setSsbmdm(this.tbBaseAdaptRemoteService.getSsbm(dto.getSsbmdm(), null));
        List<TbJcglKhtj> tbJcglKhtjs = this.baseMapper.selectList(new LambdaQueryWrapper<TbJcglKhtj>()
                .likeRight(!StringUtils.isEmpty(dto.getSsbmdm()), TbJcglKhtj::getSsbmdm, dto.getSsbmdm())
                .ge(!StringUtils.isEmpty(kssj), TbJcglKhtj::getTjrq, kssj)
                .le(!StringUtils.isEmpty(jssj), TbJcglKhtj::getTjrq, jssj)
                .orderByAsc(TbJcglKhtj::getSsbmdm, TbJcglKhtj::getTjrq)
        );
        return tbJcglKhtjs;
    }

    @Override
    public List<TbJcglKhtjVo> getFxbm(TbJcglKhtjQuery dto) {
        Map<String, String> map = this.analysisTime(dto);
        String kssj = map.get("kssj");
        String jssj = map.get("jssj");
        if (StringUtils.isEmpty(kssj) || StringUtils.isEmpty(jssj))
            throw new BusinessException("时间查询参数异常！！");
        String ssbm = this.tbBaseAdaptRemoteService.getSsbm(dto.getSsbmdm(), "");
        DeptInfoVo dept = this.tbBaseAdaptRemoteService.getOrgByOrgcode(org.apache.commons.lang3.StringUtils.rightPad(ssbm, 12, "0"));
        String orglevel = "4";
        if ("20".equals(dept.getOrgLevel()) || "30".equals(dept.getOrgLevel()) || "10".equals(dept.getOrgLevel())) {
            orglevel = "3";
        }
        Map<String, Object> mp = new HashMap<>();
        mp.put("kssj", kssj);
        mp.put("jssj", jssj);
        mp.put("bmdmList", ssbm);
        mp.put("orglevel", orglevel);
        List<TbJcglKhtjVo> fxbm = this.baseMapper.getFxbm(mp);
        return fxbm;
    }

    @Override
    public IPage<TbJcglKhtjVo> getPageList(TbJcglKhtjQuery dto) {
//        UserInfo user = UserInfoManager.get();
        Map<String, String> map = this.analysisTime(dto);
        String kssj = map.get("kssj");
        String jssj = map.get("jssj");
        if (StringUtils.isEmpty(kssj) || StringUtils.isEmpty(jssj))
            throw new BusinessException("时间查询参数异常！！");
//        if (StringUtils.isEmpty(dto.getSsbmdm())) {
//            dto.setSsbmdm(user.getDeptCode());
//        }
        Map<String, Object> mp = new HashMap<>();
        String ssbm = this.tbBaseAdaptRemoteService.getSsbm(dto.getSsbmdm(), "");
        DeptInfoVo dept = this.tbBaseAdaptRemoteService.getOrgByOrgcode(org.apache.commons.lang3.StringUtils.rightPad(ssbm, 12, "0"));
        if (!StringUtils.isEmpty(dept.getOrgLevel())) {
            if ("20".equals(dept.getOrgLevel()) || "10".equals(dept.getOrgLevel())) {
                if ("01".equals(dto.getCxcj())) {
                    mp.put("orglevel", "3");
                } else {
                    mp.put("orglevel", "4");
                }
            } else {
                mp.put("orglevel", "4");
            }
        } else {
            mp.put("orglevel", "4");
        }
        mp.put("bmdmList", ssbm);
        mp.put("kssj", kssj);
        mp.put("jssj", jssj);
        mp.put("searchType", dto.getSearchType());
        mp.put("pageIndex", (dto.getPageCurrent() - 1) * dto.getPageSize());
        mp.put("pageSize", dto.getPageSize());
        int count = this.baseMapper.getCount(mp);
        List<TbJcglKhtjVo> list = this.baseMapper.getList(mp);
        IPage<TbJcglKhtjVo> page = new Page<>(dto.getPageCurrent(), dto.getPageSize());
        page.setTotal(count);
        page.setRecords(list);
        return page;
    }

    @Override
    public Map<String, Object> getStatistics(TbJcglKhtjStatisticsQuery dto) {
        String ssbm = this.tbBaseAdaptRemoteService.getSsbm(dto.getSsbmdm(), null);
        Map<String, Object> map = new HashMap<>();
        map.put("bmdmList", ssbm);
        map.put("time", dto.getTime());
        map.put("searchType", dto.getSearchType());
        return this.baseMapper.getStatistics(map);
    }

    // 根据条件解析开始结束时间
    private Map<String, String> analysisTime(TbJcglKhtjQuery dto) {
        Map<String, String> map = new HashMap<>();
        if ("01".equals(dto.getType())) {
            if (StringUtils.isEmpty(dto.getKssj()) || StringUtils.isEmpty(dto.getJssj()))
                throw new BusinessException("请选择开始时间和结束时间");
            map.put("kssj", dto.getKssj());
            map.put("jssj", dto.getJssj());
        } else if ("02".equals(dto.getType())) {
            if (StringUtils.isEmpty(dto.getMonth()))
                throw new BusinessException("请选择月份");
            map.put("kssj", dto.getMonth() + "-01");
            map.put("jssj", dto.getMonth() + "-31");
        } else if ("03".equals(dto.getType())) {
            if (StringUtils.isEmpty(dto.getYear())) throw new BusinessException("请选择年份");
            if (StringUtils.isEmpty(dto.getQuarter())) throw new BusinessException("请选择季度");
            if ("01".equals(dto.getQuarter())) {
                map.put("kssj", dto.getYear() + "-01-01");
                map.put("jssj", dto.getYear() + "-03-31");
            } else if ("02".equals(dto.getQuarter())) {
                map.put("kssj", dto.getYear() + "-04-01");
                map.put("jssj", dto.getYear() + "-06-31");
            } else if ("03".equals(dto.getQuarter())) {
                map.put("kssj", dto.getYear() + "-07-01");
                map.put("jssj", dto.getYear() + "-09-31");
            } else if ("04".equals(dto.getQuarter())) {
                map.put("kssj", dto.getYear() + "-10-01");
                map.put("jssj", dto.getYear() + "-12-31");
            }
        } else if ("04".equals(dto.getType())) {
            if (StringUtils.isEmpty(dto.getYear())) throw new BusinessException("请选择年份");
            map.put("kssj", dto.getYear() + "-01-01");
            map.put("jssj", dto.getYear() + "-12-31");
        }
        return map;
    }

    // 计算应签收数量
    private Integer getYqs(String ssbmdm, String time) {
        return this.tbYjzlAdaptRrmoteService.getZlCount(ssbmdm, time, null);
    }

    // 计算应巡逻数
    private Integer getYxl(String ssbmdm, String time) {
        return this.tbYjzlAdaptRrmoteService.getFzyjCount(ssbmdm, time, null);
    }

    // 计算实际巡逻
    private Integer getSjxl(String ssbmdm, String time) {
        return this.tbYjzlAdaptRrmoteService.getFzyjCount(ssbmdm, time, "1");
    }

    // 计算实际签收
    private Integer getSjqs(String ssbmdm, String time) {
        return this.tbYjzlAdaptRrmoteService.getZlCount(ssbmdm, time,
                "02,03,04,11,21,22,23,24,25,26,27,31,32,91,92,93");
    }

    // 计算实际报备
    private Integer getSjbb(String ssbmdm, String time) {
        return this.tbQwzxAdaptRemoteService.getBbCount(ssbmdm, time);
    }

    // 计算实际盘查人员
    private Integer getsjpcr(String ssbmdm, String time) {
        return this.tbHczxAdaptRemoteService.getSjpcr(ssbmdm, time);
    }

    // 计算实际盘查车辆
    private Integer getsjpcc(String ssbmdm, String time) {
        return this.tbHczxAdaptRemoteService.getSjpcc(ssbmdm, time);
    }

    // 计算实际盘查物品
    private Integer getPcWptj(String ssbmdm, String time) {
        return this.tbHczxAdaptRemoteService.getPcWptj(ssbmdm, time);
    }

    // 计算实际报备
    private Map<String, Integer> getScLc(String ssbmdm, String time) {
        return this.tbQwzxAdaptRemoteService.getScLc(ssbmdm, time);
    }
}
