package com.siwei.rsmonitoring.service.impl;

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

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.siwei.common.core.constant.SecurityConstants;
import com.siwei.common.core.domain.R;
import com.siwei.common.core.exception.ServiceException;
import com.siwei.common.core.utils.DateUtils;
import com.siwei.common.core.utils.StringUtils;
import com.siwei.common.core.utils.file.FileTypeUtils;
import com.siwei.common.core.utils.file.FileUtils;
import com.siwei.common.core.utils.file.UnPackageUtils;
import com.siwei.common.core.utils.uuid.IdUtils;
import com.siwei.common.security.utils.SecurityUtils;
import com.siwei.rsmonitoring.config.StaticConfig;
import com.siwei.rsmonitoring.domain.*;
import com.siwei.rsmonitoring.domain.vo.TDkjbxxHgxRecordSplitVo;
import com.siwei.rsmonitoring.service.*;
import com.siwei.spatial.api.RemoteSpatialFilesDbService;
import com.siwei.spatial.api.domain.file.TGeomDb;
import com.siwei.spatial.api.domain.file.TGeomDbDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.siwei.rsmonitoring.mapper.TDkjbxxHgxMapper;
import org.springframework.transaction.annotation.Transactional;

/**
 * 地块基本信息合规性判定Service业务层处理
 *
 * @author siwei
 * @date 2025-02-10
 */
@Service
public class TDkjbxxHgxServiceImpl implements ITDkjbxxHgxService {
    @Autowired
    private TDkjbxxHgxMapper tDkjbxxHgxMapper;
    @Autowired
    private ITZdkjbxxService itZdkjbxxService;
    @Autowired
    private ITDkjbxxService itDkjbxxService;
    @Autowired
    private ITDkAuditflowRecordService dkAuditflowRecordService;
    @Autowired
    private ITDkAuditflowFjService itDkAuditflowFjService;
    @Autowired
    private ITDkjbxxHgxRecordService iTDkjbxxHgxRecordService;
    @Autowired
    private ITZdkjbxxService tZdkjbxxService;
    /**
     * 上传文件存储在本地的根路径
     */
    @Value("${file.path}")
    private String localFilePath;
    /**
     * 资源映射路径 前缀
     */
    @Value("${file.prefix}")
    public String localFilePrefix;
    @Autowired
    private RemoteSpatialFilesDbService remoteSpatialFilesDbService;

    /**
     * 查询地块基本信息合规性判定
     *
     * @param id 地块基本信息合规性判定主键
     * @return 地块基本信息合规性判定
     */
    @Override
    public TDkjbxxHgx selectTDkjbxxHgxById(String id) {
        return tDkjbxxHgxMapper.selectTDkjbxxHgxById(id);
    }

    @Override
    public TDkjbxxHgxRecord selectTDkjbxxHgxInfo(String dkid, String auditflowStep, String auditflowId) {
        if (StringUtils.isEmpty(dkid) || StringUtils.isEmpty(auditflowStep)) {
            return null;
        }
        TDkjbxxHgxRecord recordQuery = new TDkjbxxHgxRecord();
        recordQuery.setDkjbxxId(dkid);
        recordQuery.setAuditflowStep(auditflowStep);
        if (StringUtils.isNotEmpty(auditflowId)) {
            recordQuery.setAuditflowId(auditflowId);
        }
        List<TDkjbxxHgxRecord> dk0 = iTDkjbxxHgxRecordService.selectTDkjbxxHgxRecordList(recordQuery);
        if (dk0.isEmpty()) {
            return null;
        }
        TDkjbxxHgxRecord vo = dk0.get(0);

//        拆分状态 0是 1否
        TDkjbxxHgx tDkjbxxHgx = new TDkjbxxHgx();
        tDkjbxxHgx.setAuditflowId(vo.getAuditflowId());
        tDkjbxxHgx.setRecordId(vo.getId());
        vo.setHgxVoList(tDkjbxxHgxMapper.selectTDkjbxxHgxList(tDkjbxxHgx));

        TDkAuditflowFj tDkAuditflowFj = new TDkAuditflowFj();
        tDkAuditflowFj.setAuditflowId(vo.getAuditflowId());
        vo.setFjs(itDkAuditflowFjService.selectTDkAuditflowFjList(tDkAuditflowFj));
        return vo;
    }

    /**
     * 查询地块基本信息合规性判定列表
     *
     * @param tDkjbxxHgx 地块基本信息合规性判定
     * @return 地块基本信息合规性判定
     */
    @Override
    public List<TDkjbxxHgx> selectTDkjbxxHgxList(TDkjbxxHgx tDkjbxxHgx) {
        return tDkjbxxHgxMapper.selectTDkjbxxHgxList(tDkjbxxHgx);
    }

    /**
     * 新增地块基本信息合规性判定
     *
     * @param tDkjbxxHgx 地块基本信息合规性判定
     * @return 结果
     */
    @Override
    public int insertTDkjbxxHgx(TDkjbxxHgx tDkjbxxHgx) {
        tDkjbxxHgx.setCreateTime(DateUtils.getNowDate());
        return tDkjbxxHgxMapper.insertTDkjbxxHgx(tDkjbxxHgx);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addTDkjbxxHgx(TDkjbxxHgxRecord tDkjbxxHgxRecord) {
        if (null == tDkjbxxHgxRecord) {
            return 0;
        }
        String dkid = tDkjbxxHgxRecord.getDkjbxxId();
        if (StringUtils.isEmpty(dkid)) {
            return 0;
        }
        String auditflowStep = tDkjbxxHgxRecord.getAuditflowStep();
        if (StringUtils.isEmpty(auditflowStep)) {
            return 0;
        }
        //拆分状态 0是 1否
        Integer splitType = tDkjbxxHgxRecord.getSplitType();
        if (splitType == null) {
            return 0;
        }
        if (splitType != 1 && splitType != 0) {
            return 0;
        }
        //合规性判定情况
        List<TDkjbxxHgx> list0 = tDkjbxxHgxRecord.getHgxVoList();
        if (list0.isEmpty()) {
            return 0;
        }

        //判断是否存在
        TDkjbxx dkjbxx = itDkjbxxService.selectTDkjbxxById(dkid);
        if (dkjbxx == null) {
            return 0;
        }
        TDkjbxx dkjbxxnew_update = new TDkjbxx();
        dkjbxxnew_update.setId(dkid);
        dkjbxxnew_update.setSplitType(splitType);

        //判断是否可进行操作
        if (!dkAuditflowRecordService.isCheckUserTDkAuditflowRecord(dkjbxx.getId(), dkjbxx.getAuditflow(), auditflowStep, StaticConfig.AUDIT_FLOW_STEP_OPERATION_TYPE_001)) {
            throw new ServiceException("无权限操作");
        }

        tDkjbxxHgxRecord.setDkbh(dkjbxx.getDkbh());
        tDkjbxxHgxRecord.setDkmj(dkjbxx.getDkmj());
        tDkjbxxHgxRecord.setId(IdUtils.fastSimpleUUID());
        iTDkjbxxHgxRecordService.insertTDkjbxxHgxRecord(tDkjbxxHgxRecord);

        tZdkjbxxService.deleteTZdkjbxxById(dkjbxx.getId());
        List<String> hgxUpdateList = new ArrayList<>();
        int i = 0;
        for (TDkjbxxHgx vo_0 : list0) {
            if (null == vo_0.getSort()) {
                vo_0.setSort(i);
            }
            vo_0.setId(IdUtils.fastSimpleUUID());
            vo_0.setDkjbxxId(dkid);
            vo_0.setCreateBy(SecurityUtils.getUsername());
            vo_0.setCreateTime(DateUtils.getNowDate());
            vo_0.setRecordId(tDkjbxxHgxRecord.getId());
            tDkjbxxHgxMapper.insertTDkjbxxHgx(vo_0);
            hgxUpdateList.add(vo_0.getId());
            i++;
            //拆分进入子目录，还要进行空间验证。空间验证暂时没做，后期添加
            if (0 == splitType) {
                TZdkjbxx tZdkjbxx = new TZdkjbxx();
                tZdkjbxx.setId(dkjbxx.getId());
                tZdkjbxx.setBsm(String.valueOf(vo_0.getSort()));
                tZdkjbxx.setDkbh(dkjbxx.getDkbh());
                tZdkjbxx.setDkmj(vo_0.getArea());
                tZdkjbxx.setGeom(vo_0.getGeom());
                tZdkjbxx.setAuditflow(dkjbxx.getAuditflow());
                tZdkjbxx.setFieldworkId(vo_0.getId());
                tZdkjbxxService.insertTZdkjbxx(tZdkjbxx);
            }else{
                dkjbxxnew_update.setFieldworkId(vo_0.getId());
            }
        }

        List<String> fjUpdateList = new ArrayList<>();
        //附件
        for (TDkAuditflowFj fjObj : tDkjbxxHgxRecord.getFjs()) {
            fjObj.setDkjbxxId(dkid);
            fjObj.setId(IdUtils.fastSimpleUUID());
            fjObj.setCreateBy(SecurityUtils.getUsername());
            fjObj.setCreateTime(DateUtils.getNowDate());
            itDkAuditflowFjService.insertTDkAuditflowFj(fjObj);
            fjUpdateList.add(fjObj.getId());
        }

        //执行核查流程
        TDkAuditflowRecord tDkAuditflowRecord = new TDkAuditflowRecord();
        tDkAuditflowRecord.setDkjdxxId(dkid);
        tDkAuditflowRecord.setAuditflowType(dkjbxx.getAuditflow());
        tDkAuditflowRecord.setSuccessType("0");
        tDkAuditflowRecord.setAuditflowStep(auditflowStep);
        Map<String, String> recordData = dkAuditflowRecordService.refreshTDkAuditflowRecord(tDkAuditflowRecord);
        if (recordData.isEmpty()) {
            throw new ServiceException("流程失败");
        }
        //当前核查流程编号
        String currentId = recordData.get("current");
        deleteAuditflowId(currentId);

        //更新标志
        for (String idObj : fjUpdateList) {
            TDkAuditflowFj tDkAuditflowFj = new TDkAuditflowFj();
            tDkAuditflowFj.setId(idObj);
            tDkAuditflowFj.setAuditflowId(currentId);
            itDkAuditflowFjService.updateTDkAuditflowFj(tDkAuditflowFj);
        }

        for (String idObj : hgxUpdateList) {
            TDkjbxxHgx tDkjbxxHgx = new TDkjbxxHgx();
            tDkjbxxHgx.setId(idObj);
            tDkjbxxHgx.setAuditflowId(currentId);
            tDkjbxxHgxMapper.updateTDkjbxxHgx(tDkjbxxHgx);
        }

        itDkjbxxService.updateTDkjbxxByHgx(dkjbxxnew_update);

        TDkjbxxHgxRecord tDkjbxxHgxRecordUpdate = new TDkjbxxHgxRecord();
        tDkjbxxHgxRecordUpdate.setId(tDkjbxxHgxRecord.getId());
        tDkjbxxHgxRecordUpdate.setSplitType(splitType);
        tDkjbxxHgxRecordUpdate.setAuditflowId(currentId);
        iTDkjbxxHgxRecordService.updateTDkjbxxHgxRecord(tDkjbxxHgxRecordUpdate);
        return 1;
    }

    private void deleteAuditflowId(String auditflowId) {
        //删除之前上传的数据
        itDkAuditflowFjService.deleteTDkAuditflowFjByAuditflowId(auditflowId);
        TDkjbxxHgxRecord tDkjbxxHgxRecord = new TDkjbxxHgxRecord();
        tDkjbxxHgxRecord.setAuditflowId(auditflowId);
        List<TDkjbxxHgxRecord> removerList = iTDkjbxxHgxRecordService.selectTDkjbxxHgxRecordList(tDkjbxxHgxRecord);
        for (TDkjbxxHgxRecord hgx : removerList) {
            iTDkjbxxHgxRecordService.deleteTDkjbxxHgxRecordById(hgx.getId());
        }

        TDkjbxxHgx tDkjbxxHgx = new TDkjbxxHgx();
        tDkjbxxHgx.setAuditflowId(auditflowId);
        List<TDkjbxxHgx> removerListHgx = tDkjbxxHgxMapper.selectTDkjbxxHgxList(tDkjbxxHgx);
        for (TDkjbxxHgx hgx : removerListHgx) {
            tDkjbxxHgxMapper.deleteTDkjbxxHgxById(hgx.getId());
        }

    }

    /**
     * 修改地块基本信息合规性判定
     *
     * @param tDkjbxxHgx 地块基本信息合规性判定
     * @return 结果
     */
    @Override
    public int updateTDkjbxxHgx(TDkjbxxHgx tDkjbxxHgx) {
        return tDkjbxxHgxMapper.updateTDkjbxxHgx(tDkjbxxHgx);
    }

    /**
     * 批量删除地块基本信息合规性判定
     *
     * @param ids 需要删除的地块基本信息合规性判定主键
     * @return 结果
     */
    @Override
    public int deleteTDkjbxxHgxByIds(String[] ids) {
        return tDkjbxxHgxMapper.deleteTDkjbxxHgxByIds(ids);
    }

    /**
     * 删除地块基本信息合规性判定信息
     *
     * @param id 地块基本信息合规性判定主键
     * @return 结果
     */
    @Override
    public int deleteTDkjbxxHgxById(String id) {
        return tDkjbxxHgxMapper.deleteTDkjbxxHgxById(id);
    }

    @Override
    public List<TDkjbxxHgxRecordSplitVo> splitTDkjbxxHgx(TDkjbxxHgxRecordSplitVo tDkjbxxHgxRecordSplitVo) {
        //解压zip
        String zipPath = tDkjbxxHgxRecordSplitVo.getPath();
        zipPath = localFilePath + zipPath;
        if (!FileTypeUtils.getFileType(zipPath).equalsIgnoreCase("zip")) {
            throw new ServiceException("文件类型不是zip");
        }
        File zipFile = new File(zipPath);
        if (!zipFile.exists()) {
            throw new ServiceException("zip文件不存在");
        }
        //加压路径
        String unZipPath = zipPath.substring(0, zipPath.length() - 4);
        System.out.println(zipPath);
        System.out.println(unZipPath);
        UnPackageUtils.unPackZip(zipPath, unZipPath, null);

        //判断shp文件是否存在
        List<File> shpFiles = new ArrayList<>();
        FileUtils.findTypeByFiles(unZipPath, shpFiles, new String[]{".shp"});
        if (shpFiles.isEmpty()) {
            throw new ServiceException("shp文件不存在");
        }
        File shpPile = shpFiles.get(0);
        //获取文件夹
        String paremtFilePath = shpPile.getParentFile().getAbsolutePath();
        String db0_local_path = localFilePath.replaceAll("\\\\", "/").replaceAll("//", "/");
        String db0_paremt_path = paremtFilePath.replaceAll("\\\\", "/").replaceAll("//", "/");
        String db0_shp_path = shpPile.getAbsolutePath();
        String ppp = db0_shp_path.substring(db0_paremt_path.indexOf(db0_local_path) + db0_local_path.length());

        //解析shp文件
        R<TGeomDb> readShpResult = remoteSpatialFilesDbService.readShp(shpPile.getName(), ppp, "TDkGeomDbServiceImpl.insertTDkGeomDb", SecurityConstants.INNER);
        if (R.FAIL == readShpResult.getCode()) {
            throw new ServiceException("解析shp文件出错");
        }
        TGeomDb db = readShpResult.getData();
        if (db == null) {
            throw new ServiceException("解析shp文件出错");
        }

        //解析shp文件
        R<List<TGeomDbDetails>> readShpGeomDetails = remoteSpatialFilesDbService.queryGeomDetails(db.getId(), SecurityConstants.INNER);
        if (R.FAIL == readShpGeomDetails.getCode()) {
            throw new ServiceException("解析shp文件出错");
        }
        List<TGeomDbDetails> dbDetails = readShpGeomDetails.getData();
        String dbDetailJson = null;
        Set<String> sortSet = new HashSet<>();
        int i = 0;
        List<TDkjbxxHgxRecordSplitVo> retList = new ArrayList<>();
        for (TGeomDbDetails dbDetail : dbDetails) {
            dbDetailJson = dbDetail.getGeomJson();
            if (StringUtils.isEmpty(dbDetailJson)) {
                throw new ServiceException("解析shp文件出错");
            }
//            swid(swid) *
//            合法性 *
//            合法性1 *
//            面积 (压占面积总和(亩)) *
//            面积集 (压占面积(亩)) *
//            编号集 (压占数据编号) *
            //* 标注为必须字段,不可为空。其他为选配字段 如果还有其他字段，将统一放入到JSON字段中
            JSONObject jsonObject = JSON.parseObject(dbDetailJson);
            //获取属性字段，并将字段进行赋值。获取成功的将删除该KEY
            String jcbh = jsonObject.getString("jcbh");
            BigDecimal jcmj = jsonObject.getBigDecimal("jcmj");
            String hfxpd = jsonObject.getString("hfxpd");
            String pdlx = jsonObject.getString("pdlx");
            String bz = jsonObject.getString("bz");
            String sort = jsonObject.getString("sort");
            if (StringUtils.isEmpty(jcbh) || StringUtils.isEmpty(hfxpd) || null == jcmj || StringUtils.isEmpty(pdlx)) {
                throw new ServiceException("shp属性字段缺失");
            }
            if (tDkjbxxHgxRecordSplitVo.getDkbh().equals(jcbh)) {
                if (StringUtils.isEmpty(sort) || sortSet.contains(sort)) {
                    i = checkSetSort(i, sortSet);
                    sort = i + "";
                }
                sortSet.add(sort);
                TDkjbxxHgxRecordSplitVo newVo = new TDkjbxxHgxRecordSplitVo();
                newVo.setDecide(hfxpd);
                newVo.setDecideType(pdlx);
                newVo.setNotes(bz);
                newVo.setArea(jcmj.toString());
                newVo.setGeom(dbDetail.getGeom());
                newVo.setSort(sort);
                retList.add(newVo);
            }
        }
        return retList;
    }

    private int checkSetSort(int i, Set<String> sortSet) {
        boolean bo = true;
        while (bo) {
            String vi = i + "";
            if (!sortSet.contains(vi)) {
                bo = false;
            }
            if (bo) {
                i++;
            }
        }
        return i;
    }
}
