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.google.common.collect.ImmutableList;
import com.mosty.base.model.dto.qwzx.AppSearchQuery;
import com.mosty.base.model.dto.yszx.TbYsGajgDto;
import com.mosty.base.model.entity.jcgl.TbJcglXfcl;
import com.mosty.base.model.entity.jcgl.TbJcglXfll;
import com.mosty.base.model.entity.qwzx.TbQwQwbc;
import com.mosty.base.model.query.jcgl.XfqyQuery;
import com.mosty.base.utils.DateUtils;
import com.mosty.base.utils.GeoHashKit;
import com.mosty.base.utils.JtsUtils;
import com.mosty.base.utils.UUIDGenerator;
import com.mosty.base.model.vo.base.DeptInfoVo;
import com.mosty.base.model.dto.jcgl.TbJcglXfqyDto;
import com.mosty.base.model.entity.jcgl.TbJcglXfqy;
import com.mosty.base.model.query.jcgl.TbJcglXfqyQuery;
import com.mosty.base.manager.mapper.TbJcglXfqyMapper;
import com.mosty.base.manager.remote.TbBaseAdaptRemoteService;
import com.mosty.base.manager.remote.TbYsZxAdaptRemoteService;
import com.mosty.base.manager.service.TbJcglXfqyService;
import com.mosty.common.base.exception.BusinessException;
import com.mosty.common.token.UserInfo;
import com.mosty.common.token.UserInfoManager;
import com.mosty.common.util.PermissionsUtil;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

/**
 * @author zengbo
 * @since 2022-07-14
 */
@AllArgsConstructor
@Service
public class TbJcglXfqyServiceImpl extends ServiceImpl<TbJcglXfqyMapper, TbJcglXfqy>
        implements TbJcglXfqyService {

    private TbBaseAdaptRemoteService tbBaseAdaptRemoteService;
    private TbYsZxAdaptRemoteService tbYsZxAdaptRemoteService;

    @Override
    @Transactional
    public int addXfqy(TbJcglXfqyDto xfqy) {
        TbJcglXfqy item = new TbJcglXfqy();
        BeanUtils.copyProperties(xfqy, item);
        if (xfqy.getJd() != null && xfqy.getWd() != null) {
            item.setZxd(JtsUtils.getPoint(xfqy.getJd(), xfqy.getWd()));
            item.setZbhash(GeoHashKit.encode(xfqy.getJd(), xfqy.getWd()));
        }
        if (!CollectionUtils.isEmpty(xfqy.getPgis())) item.setPgis(JtsUtils.getPolygon(xfqy.getPgis()));
        item.setId(UUIDGenerator.getUUID());
        if (StringUtils.isNotBlank(xfqy.getSsbmdm())) {
            DeptInfoVo dept = this.tbBaseAdaptRemoteService.getOrgByOrgcode(item.getSsbmdm());
            item.setSsbm(dept.getOrgJc());
            item.setSsbmid(dept.getDeptid());
            item.setSsbmdm(dept.getDeptcode());
            item.setSsxgajdm(dept.getFxjcode());
            item.setSsxgajid(dept.getFxjid());
            item.setSsxgaj(dept.getFxjname());
            item.setSssgaj(dept.getDszname());
            item.setSssgajdm(dept.getDszcode());
            item.setSssgajid(dept.getDszid());
        }
        item.setXtSjly("1");
        int ret = this.baseMapper.insertEntity(item);
        //封装数据
        TbYsGajgDto ysGajgDto = new TbYsGajgDto();
        ysGajgDto.setLyid(item.getId());
        ysGajgDto.setLybm("tb_jcgl_xfqy");
        ysGajgDto.setYsdl("001");
        ysGajgDto.setYszl("001001");
        ysGajgDto.setYsxl("001001006");
        ysGajgDto.setGajgmc(item.getXfqMc());
        ysGajgDto.setGajgjc(item.getXfqMc());
        ysGajgDto.setJd(item.getJd());
        ysGajgDto.setWd(item.getWd());
        // 设置巡防区域面积
        List<BigDecimal> list = new ArrayList<>();
        if (!CollectionUtils.isEmpty(xfqy.getPgis())) {
            xfqy.getPgis().forEach(it -> {
                list.add(it[0]);
                list.add(it[1]);
            });
        }
        ysGajgDto.setQy(list);
        ysGajgDto.setSsbm(item.getSsbm());
        ysGajgDto.setSsbmdm(item.getSsbmdm());
        ysGajgDto.setSsbmid(item.getSsbmid());
        ysGajgDto.setBz(xfqy.getXfbmlx());
        ysGajgDto.setColor(xfqy.getColor());
        tbYsZxAdaptRemoteService.addGajg(ysGajgDto);
        return ret;
    }

    @Override
    public IPage<TbJcglXfqyDto> getXfqy(TbJcglXfqyQuery dto) {
        dto.setSsbmdm(this.tbBaseAdaptRemoteService.getSsbm(dto.getSsbmdm(), null));
        Map<String, Object> map = new HashMap<>();
        map.put("dto", dto);
//        UserInfo userInfo = UserInfoManager.get();
//        String useSql = PermissionsUtil.createSql("", userInfo);
        IPage<TbJcglXfqyDto> page = new Page<>(dto.getPageCurrent(), dto.getPageSize());
        map.put("pageIndex", (dto.getPageCurrent() - 1) * dto.getPageSize());
        map.put("pageSize", dto.getPageSize());
//        map.put("useSql", useSql);
        int count = this.baseMapper.getCount(map);
        List<TbJcglXfqy> list = this.baseMapper.getPageList(map);
        List<TbJcglXfqyDto> rList = new ArrayList<>();
        list.forEach(item -> {
            TbJcglXfqyDto vo = new TbJcglXfqyDto();
            BeanUtils.copyProperties(item, vo);
            if (item.getPgis() != null) vo.setPgis(JtsUtils.decodePolygon(item.getPgis()));
            rList.add(vo);
        });
        page.setRecords(rList);
        page.setTotal(count);
        return page;
    }

    @Override
    @Transactional
    public int editXfqy(TbJcglXfqyDto xfqy) {
        TbJcglXfqy item = new TbJcglXfqy();
        BeanUtils.copyProperties(xfqy, item);
        if (xfqy.getJd() != null && xfqy.getWd() != null) {
            item.setZxd(JtsUtils.getPoint(xfqy.getJd(), xfqy.getWd()));
            item.setZbhash(GeoHashKit.encode(xfqy.getJd(), xfqy.getWd()));
        }
        if (!CollectionUtils.isEmpty(xfqy.getPgis())) item.setPgis(JtsUtils.getPolygon(xfqy.getPgis()));
        if (StringUtils.isNotBlank(xfqy.getSsbmdm())) {
            DeptInfoVo dept = this.tbBaseAdaptRemoteService.getOrgByOrgcode(item.getSsbmdm());
            item.setSsbm(dept.getOrgJc());
            item.setSsbmid(dept.getDeptid());
            item.setSsbmdm(dept.getDeptcode());
            item.setSsxgajdm(dept.getFxjcode());
            item.setSsxgajid(dept.getFxjid());
            item.setSsxgaj(dept.getFxjname());
            item.setSssgaj(dept.getDszname());
            item.setSssgajdm(dept.getDszcode());
            item.setSssgajid(dept.getDszid());
        }
        int ret = this.baseMapper.updateEntity(item);
        //封装数据
        TbYsGajgDto ysGajgDto = new TbYsGajgDto();
        ysGajgDto.setLyid(item.getId());
        ysGajgDto.setLybm("tb_jcgl_xfqy");
        ysGajgDto.setYsdl("001");
        ysGajgDto.setYszl("001001");
        ysGajgDto.setYsxl("001001006");
        ysGajgDto.setGajgmc(item.getXfqMc());
        ysGajgDto.setGajgjc(item.getXfqMc());
        ysGajgDto.setJd(item.getJd());
        ysGajgDto.setWd(item.getWd());// 设置巡防区域面积
        List<BigDecimal> list = new ArrayList<>();
        if (!CollectionUtils.isEmpty(xfqy.getPgis())) {
            xfqy.getPgis().forEach(it -> {
                list.add(it[0]);
                list.add(it[1]);
            });
        }
        ysGajgDto.setQy(list);
        ysGajgDto.setSsbm(item.getSsbm());
        ysGajgDto.setSsbmdm(item.getSsbmdm());
        ysGajgDto.setSsbmid(item.getSsbmid());
        ysGajgDto.setBz(xfqy.getXfbmlx());
        ysGajgDto.setColor(xfqy.getColor());
        tbYsZxAdaptRemoteService.updateGajg(ysGajgDto);
        return ret;
    }

    @Override
    @Transactional
    public int deleteXfqy(List<String> list) {
        int ret = this.baseMapper.deleteBatch(list);
        for (String s : list) {
            TbYsGajgDto ysGajgDto = new TbYsGajgDto();
            ysGajgDto.setLyid(s);
            ysGajgDto.setLybm("tb_jcgl_xfqy");
            tbYsZxAdaptRemoteService.delEntity(ysGajgDto);
        }
        return ret;
    }

    @Override
    public TbJcglXfqyDto selectById(String id) {
        TbJcglXfqy item = this.baseMapper.getById(id);
        if (item != null) {
            TbJcglXfqyDto vo = new TbJcglXfqyDto();
            BeanUtils.copyProperties(item, vo);
            if (item.getPgis() != null) vo.setPgis(JtsUtils.decodePolygon(item.getPgis()));
            return vo;
        }
        return null;
    }

    @Override
    public Page<TbJcglXfqy> getXfqList(AppSearchQuery dto) {
        UserInfo user = UserInfoManager.get();
        LambdaQueryWrapper<TbJcglXfqy> wrapper = new LambdaQueryWrapper<TbJcglXfqy>()
                .eq(TbJcglXfqy::getXtSjzt, "1")
                .eq(StringUtils.isNotBlank(dto.getXfqSx()), TbJcglXfqy::getXfqSx, dto.getXfqSx());
        if ("1".equals(dto.getType())) {
            wrapper.like(StringUtils.isNotBlank(dto.getKeyword()), TbJcglXfqy::getXfqMc, dto.getKeyword())
//                    .eq(TbJcglXfqy::getSsbmdm, String.valueOf(user.getDeptCode()));
                    .likeRight(TbJcglXfqy::getSsbmdm, user.getDeptCode().substring(0, 6));
        } else {
            String ssbm = this.tbBaseAdaptRemoteService.getSsbm(dto.getSsbmdm(), null);
            wrapper.likeRight(StringUtils.isNotBlank(ssbm), TbJcglXfqy::getSsbmdm, ssbm)
                    .and(StringUtils.isNotBlank(dto.getKeyword()),
                            it -> it.like(TbJcglXfqy::getXfqMc, dto.getKeyword())
                                    .or()
                                    .like(TbJcglXfqy::getSsbm, dto.getKeyword())
                    );
        }
        Page<TbJcglXfqy> tbJcglXfqyPage = this.baseMapper.selectPage(new Page<>(dto.getPageCurrent(), dto.getPageSize()), wrapper);
        if (ObjectUtils.isNotEmpty(tbJcglXfqyPage) && !CollectionUtils.isEmpty(tbJcglXfqyPage.getRecords())) {
            tbJcglXfqyPage.getRecords().forEach(item -> {
                item.setZxd(null);
                item.setPgis(null);
            });
        }
        return tbJcglXfqyPage;
    }

    /**
     * 泸州态势统计-各区县重点巡防区域
     *
     * @param dto
     * @return
     */
    @Override
    public Map<String, Object> getZdxfqy(XfqyQuery dto) {
        HashMap<Object, Object> ssxgajxx = new HashMap<>();
        ssxgajxx.put("10111", "泸州机场");
        ssxgajxx.put("10929", "江阳区");
        ssxgajxx.put("11336", "龙马潭区");
        ssxgajxx.put("11379", "纳溪区");
        ssxgajxx.put("11382", "泸县");
        ssxgajxx.put("11436", "合江县");
        ssxgajxx.put("11503", "叙永县");
        ssxgajxx.put("11531", "古蔺县");

        if (StringUtils.isEmpty(dto.getKssj()) || StringUtils.isEmpty(dto.getJssj())) { // 为空的提示
            throw new BusinessException("请选择您要查询时间！");
        }
        Map<String, Object> map = new HashMap<>();
        // 巡防总数
        List<Map<String, Object>> sfzs = this.baseMapper.getSfzs();
        // 巡防重点数
        List<Map<String, Object>> sfzd = this.baseMapper.getSfzd(dto.getKssj(), dto.getJssj());

        List<Map<String, Object>> sfzsResList = new ArrayList<>();
        List<Map<String, Object>> sfzdResList = new ArrayList<>();
        ssxgajxx.keySet().forEach(item -> {
            Map<String, Object> resMap = new HashMap<>();
            // 巡防总数
            List<Map<String, Object>> sfzsList = sfzs.stream().filter(it -> String.valueOf(it.get("ssxgajid")).equals(item)).collect(Collectors.toList());
            resMap.put("ssxgaj", ssxgajxx.get(item));
            resMap.put("ssxgajid", item);
            if (sfzsList.size() == 1) {
                resMap.put("count", sfzsList.get(0).get("count"));
            } else {
                resMap.put("count", 0);
            }
            sfzsResList.add(resMap);

            // 巡防重点数
            resMap = new HashMap<>();
            List<Map<String, Object>> sfzdList = sfzd.stream().filter(it -> String.valueOf(it.get("ssxgajid")).equals(item)).collect(Collectors.toList());
            resMap.put("ssxgaj", ssxgajxx.get(item));
            resMap.put("ssxgajid", item);
            if (sfzdList.size() == 1) {
                resMap.put("count", sfzdList.get(0).get("count"));
            } else {
                resMap.put("count", 0);
            }
            sfzdResList.add(resMap);
        });

        map.put("sfzsResList", sfzsResList);
        map.put("sfzdResList", sfzdResList);
        return map;
    }


    @Override
    public List<TbJcglXfqyDto> getListAll() {
        List<TbJcglXfqy> list = this.baseMapper.getListAll();
        List<TbJcglXfqyDto> rList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(item -> {
                TbJcglXfqyDto vo = new TbJcglXfqyDto();
                BeanUtils.copyProperties(item, vo);
                if (item.getPgis() != null) vo.setPgis(JtsUtils.decodePolygon(item.getPgis()));
                rList.add(vo);
            });
        }
        return rList;
    }

    /**
     * 泸州态势统计-警情与重点区域巡逻对比分析
     *
     * @param dto
     * @return
     */
    @Override
    public Map<String, Object> getJqandQyxf(XfqyQuery dto) {
        if (com.mosty.common.base.util.StringUtils.isEmpty(dto.getKssj()) || com.mosty.common.base.util.StringUtils.isEmpty(dto.getJssj())) {
            throw new BusinessException("请选择查询时间");
        }
        Map<String, Object> map = new HashMap<>();
        if (dto.getKssj().equals(dto.getJssj())) {
            // 查询警情数据
            List<Map<String, Object>> jqList = this.baseMapper.getJqTj(dto.getKssj());
            // 重点区域巡防次数
            List<Map<String, Object>> sfzdList = this.baseMapper.getSfzd(dto.getKssj(), dto.getJssj());
            List<String> timeList = ImmutableList.of("00", "01", "02", "03", "04", "05", "06", "07", "08", "09",
                    "10", "11", "12", "13", "14", "15", "16", "17",
                    "18", "19", "20", "21", "22", "23");
            timeList.forEach(item -> {
                boolean jqFlag = false;
                boolean sfzdFlase = false;
                for (Map<String, Object> jq : jqList) {
                    String time = String.valueOf(jq.get("time")).length() == 1 ?
                            "0" + jq.get("time") : String.valueOf(jq.get("time"));
                    if (item.equals(time)) {
                        jqFlag = true;
                    }
                }
                for (Map<String, Object> jq : sfzdList) {
                    String time = String.valueOf(jq.get("time")).length() == 1 ?
                            "0" + jq.get("time") : String.valueOf(jq.get("time"));
                    if (item.equals(time)) {
                        sfzdFlase = true;
                    }
                }
                if (!jqFlag) {
                    Map<String, Object> mp = new HashMap<>();
                    mp.put("time", item);
                    mp.put("count", 0);
                    jqList.add(mp);
                }
                if (!sfzdFlase) {
                    Map<String, Object> mp = new HashMap<>();
                    mp.put("time", item);
                    mp.put("count", 0);
                    sfzdList.add(mp);
                }
            });
            jqList.sort(Comparator.comparingInt(a -> Integer.parseInt(a.get("time").toString())));
            sfzdList.sort(Comparator.comparingInt(a -> Integer.parseInt(a.get("time").toString())));
            map.put("jqList", jqList.stream().map(item -> item.get("count")).collect(Collectors.toList()));
            map.put("sfzdList", sfzdList.stream().map(item -> item.get("count")).collect(Collectors.toList()));
        } else {
            // 警情
            List<Map<String, Object>> jqList = this.baseMapper.getJqTjByTime(dto.getKssj(), dto.getJssj());
            // 重点区域巡防次数
            List<Map<String, Object>> sfzdList = this.baseMapper.getXfzdByTime(dto.getKssj(), dto.getJssj());
            Date kssj = DateUtils.strToDate(dto.getKssj(), "01");
            Date jssj = DateUtils.strToDate(dto.getJssj(), "01");
            while (kssj.getTime() <= jssj.getTime()) {
                boolean jqFlag = false;
                boolean xfzdFlag = false;
                for (Map<String, Object> item : jqList) {
                    if (String.valueOf(item.get("time")).equals(DateUtils.getQueryDateString(kssj, "01"))) {
                        jqFlag = true;
                    }
                }
                for (Map<String, Object> item : sfzdList) {
                    if (String.valueOf(item.get("time")).equals(DateUtils.getQueryDateString(kssj, "01"))) {
                        xfzdFlag = true;
                    }
                }
                if (!xfzdFlag) {
                    Map<String, Object> mp = new HashMap<>();
                    mp.put("time", DateUtils.getQueryDateString(kssj, "01"));
                    mp.put("count", 0);
                    sfzdList.add(mp);
                }
                if (!jqFlag) {
                    Map<String, Object> mp = new HashMap<>();
                    mp.put("time", DateUtils.getQueryDateString(kssj, "01"));
                    mp.put("count", 0);
                    jqList.add(mp);
                }
                kssj = DateUtils.getNextDate(kssj, "D", 1);
            }
            jqList.sort((a, b) -> {
                Date k = DateUtils.strToDate(a.get("time").toString(), "01");
                Date j = DateUtils.strToDate(b.get("time").toString(), "01");
                return (int) (k.getTime() - j.getTime());
            });
            sfzdList.sort((a, b) -> {
                Date k = DateUtils.strToDate(a.get("time").toString(), "01");
                Date j = DateUtils.strToDate(b.get("time").toString(), "01");
                return (int) (k.getTime() - j.getTime());
            });
            map.put("jqList", jqList.stream().map(item -> item.get("count")).collect(Collectors.toList()));
            map.put("sfzdList", sfzdList.stream().map(item -> item.get("count")).collect(Collectors.toList()));
        }
        return map;
    }
}
