package com.fastbee.system.service.impl;

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


import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.fastbee.common.exception.ServiceException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fastbee.system.mapper.SysDistrictMapper;
import com.fastbee.system.domain.SysDistrict;
import com.fastbee.system.service.ISysDistrictService;


/**
 * 行政区划Service业务层处理
 * 
 * @author kerwincui
 * @date 2024-10-18
 */
@Service
public class SysDistrictServiceImpl implements ISysDistrictService 
{
    @Autowired
    private SysDistrictMapper sysDistrictMapper;

    /**
     * 查询行政区划
     * 
     * @param id 行政区划主键
     * @return 行政区划
     */
    @Override
    public SysDistrict selectSysDistrictById(Long id)
    {

        return sysDistrictMapper.selectSysDistrictById(id);
    }

    /**
     * 查询行政区划列表
     * 
     * @param sysDistrict 行政区划
     * @return 行政区划
     */
    @Override
    public List<SysDistrict> selectSysDistrictList(SysDistrict sysDistrict)
    {
        return sysDistrictMapper.selectSysDistrictList(sysDistrict);
    }

    /**
     * 新增行政区划
     *
     * @param sysDistrict 行政区划
     * @return 结果
     */
    @Override
    public int insertSysDistrict(SysDistrict sysDistrict)
    {
        //校验必填项adCode
        if(Objects.isNull(sysDistrict.getAdcode())){
            throw new ServiceException("行政区划编码不能为空！");
        }
        //检验adCode不能重复
        List<SysDistrict> sysDistrictList = new LambdaQueryChainWrapper<>(sysDistrictMapper).select(SysDistrict::getId)
                .eq(SysDistrict::getAdcode, sysDistrict.getAdcode()).list();
        if(!sysDistrictList.isEmpty()){
           throw new ServiceException("行政区划编码重复！");
        }
        //校验adCode长度、
        if(sysDistrict.getAdcode().toString().trim().length() != 12){
            throw new ServiceException("行政区划编码长度必须为12位数字！");
        }
        //校验必填项name
        if(StringUtils.isBlank(sysDistrict.getName())){
            throw new ServiceException("行政区划名称不能为空！");
        }
        //校验必填项level
        if(Objects.isNull(sysDistrict.getLevel())){
            throw new ServiceException("行政区划级别不能为空！");
        }
        //是否上传行政区划
        String mapOutlineUrl = sysDistrict.getMapOutlineUrl();
        //未上传行政区划轮廓不做处理
        if(StringUtils.isBlank(mapOutlineUrl)){
            return sysDistrictMapper.insertSysDistrict(sysDistrict);
        }
        verifySaveJsonData(sysDistrict, mapOutlineUrl);
        return sysDistrictMapper.insertSysDistrict(sysDistrict);
    }

    /**
     * 验证并保存轮廓json数据
     * @param mapOutlineUrl  地图轮廓json文件访问uel
     */
    private void verifySaveJsonData(SysDistrict sysDistrict, String mapOutlineUrl) {
        //行政区划轮廓json文件url是绝对url代表新上传过
        if(!(mapOutlineUrl.contains("http://") || mapOutlineUrl.contains("https://"))){
            return ;
        }
        //上传行政区划轮廓进行数据处理
        String jsonData = HttpUtil.get(mapOutlineUrl);
        System.err.println("获取到行政区划轮廓json:"+jsonData);
        //读取文件内容
        if (Objects.isNull(jsonData)) {
            throw new ServiceException("上传行政区划地图轮廓json数据为空！");
        }
        //校验文件内容是否是json格式
        if (!isValidJson(jsonData)) {
            throw new ServiceException("json格式不正确！");
        }
        //保存相对路径
        int startIndex = mapOutlineUrl.indexOf("/profile/upload/");
        String relativeUrl = mapOutlineUrl.substring(startIndex);
        sysDistrict.setMapOutlineUrl(relativeUrl);
        sysDistrict.setMapOutline(jsonData);
    }

    /**
     * 修改行政区划
     */
    @Override
    public int updateSysDistrict(SysDistrict sysDistrict)
    {
        String mapOutlineUrl = sysDistrict.getMapOutlineUrl();
        //未上传行政区划轮廓不做处理
        if(StringUtils.isBlank(mapOutlineUrl)){
            return sysDistrictMapper.updateSysDistrict(sysDistrict);
        }
        //判断行政区划轮廓json文件路url是否是完整url还是相对url,如果是相对url则代表并未修改，绝对url代表修改过
        verifySaveJsonData(sysDistrict, mapOutlineUrl);

        return sysDistrictMapper.updateSysDistrict(sysDistrict);
    }

    /**
     * 验证字符串是否是json格式
     */
    public  boolean isValidJson(String jsonStr) {
        try {
            JSONUtil.parseObj(jsonStr);
        } catch (JSONException e) {
            return false;
        }
        return true;
    }

    /**
     * 批量删除行政区划
     */
    @Override
    public int deleteSysDistrictByIds(Long[] ids)
    {
        return sysDistrictMapper.deleteSysDistrictByIds(ids);
    }

    /**
     * 删除行政区划信息
     */
    @Override
    public int deleteSysDistrictById(Long id)
    {
        return sysDistrictMapper.deleteSysDistrictById(id);
    }


    /**
     * 查询指定地区行政区划树状列表
     */
    @Override
    public List<SysDistrict> selectSysDistrictTreeByCode(Long areaCode) {
        LambdaQueryChainWrapper<SysDistrict> sysDistrictLambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(sysDistrictMapper)
                .select(SysDistrict::getId, SysDistrict::getParentId, SysDistrict::getName, SysDistrict::getAdcode,
                        SysDistrict::getLevel, SysDistrict::getFullName, SysDistrict::getName
                        , SysDistrict::getLng, SysDistrict::getLat);
        //获取子级别
        List<SysDistrict> sysDistrictList = sysDistrictLambdaQueryChainWrapper.eq(SysDistrict::getAdcode, areaCode)
                .list();
        if (Objects.isNull(sysDistrictList) || sysDistrictList.isEmpty()) {
            throw new ServiceException("未查询到指定地区行政区划树状列表！");
        }

        //查询全部
        List<SysDistrict> sysDistrictListAll =  new LambdaQueryChainWrapper<>(sysDistrictMapper)
                .select(SysDistrict::getId, SysDistrict::getParentId, SysDistrict::getName, SysDistrict::getAdcode,
                        SysDistrict::getLevel, SysDistrict::getFullName, SysDistrict::getName
                        , SysDistrict::getLng, SysDistrict::getLat)
                .ge(SysDistrict::getAdcode, areaCode)
                .lt(SysDistrict::getAdcode, (Long.parseLong(areaCode.toString().substring(0,2))+1)*10000000000L)
                .list();
        System.err.println("查询到全部列表上限条件");
        System.err.println(((Long.parseLong(areaCode.toString().substring(0,2))+1)*10000000000L));
        List<SysDistrict> sysDistricts = buildTree(sysDistrictListAll);
        return Collections.singletonList(sysDistricts.get(0));
    }

    /**
     * 根据地区代码获取行政区划信息
     */
    @Override
    public SysDistrict selectSysDistrictByCode(Long areaCode) {
        return sysDistrictMapper.selectSysDistrictByCode(areaCode);
    }

    /**
     * 查询行政区划树状列表
     */
    @Override
    public List<SysDistrict> selectSysDistrictTree(Integer level) {
        System.err.println("等级:level:"+level);
        //计算查询用时
        long startTime = System.currentTimeMillis();
        List<SysDistrict> sysDistrictList = new LambdaQueryChainWrapper<>(sysDistrictMapper)
                .select(SysDistrict::getId,SysDistrict::getAdcode, SysDistrict::getParentId,SysDistrict::getLevel,
                        SysDistrict::getName, SysDistrict::getFullName )
                .ge(Objects.nonNull(level),SysDistrict::getLevel, level)
                .list();
        System.err.println("查询用时:"+(System.currentTimeMillis()-startTime));
        return buildTree(sysDistrictList);
    }

    private List<SysDistrict> buildTree(List<SysDistrict> SysDistricts) {
        Map<Long, SysDistrict> map = new HashMap<>();
        List<SysDistrict> roots = new ArrayList<>();
        for (SysDistrict sysDistrict : SysDistricts) {
            //处理直辖市情况
            if (!map.containsKey(sysDistrict.getAdcode())) {
                map.put(sysDistrict.getAdcode(), sysDistrict);
            }
        }
        List<SysDistrict> sysDistrictList = getDistricts(SysDistricts, map, roots);
        //处理直辖市情况
        for (SysDistrict sysDistrict : sysDistrictList) {
            if(isMunicipality(sysDistrict.getName())&&sysDistrict.getLevel()==1){
                List<SysDistrict> children = sysDistrict.getChildren();
                SysDistrict district = children.get(0);
                children.remove(0);
                sysDistrict.setChildren(Collections.singletonList(district));
                sysDistrict.getChildren().get(0).setChildren(children);
            }
        }
        return sysDistrictList;
    }

    /**
     * 判断是否是直辖市
     * @param name 行政区域名称
     * @return true:是  false:不是
     */
    private Boolean isMunicipality(String name) {
        return name.equals("北京")||name.equals("天津") ||name.equals("上海")||name.equals("重庆");
    }
    private List<SysDistrict> getDistricts(List<SysDistrict> SysDistricts, Map<Long, SysDistrict> map, List<SysDistrict> roots) {
        for (SysDistrict sysDistrict : SysDistricts) {
            Long parentId = sysDistrict.getParentId();
            //如果父节点为空或者父节点不在map中，则该节点为根节点
            if (parentId == null || !map.containsKey(parentId)) {
                roots.add(sysDistrict);
            }
            else {
                SysDistrict parent = map.get(parentId);
                if (parent.getChildren() == null) {
                    parent.setChildren(new ArrayList<>());
                }
                parent.getChildren().add(sysDistrict);
            }
        }
        return roots;
    }

}
