package com.zjrs.zwnw.sxgl.bpo.impl;

import org.apache.commons.lang.StringUtils;
import org.mohrss.leaf.core.framework.domain.bpo.impl.BPOImpl;
import org.mohrss.leaf.core.framework.persistens.PageResult;
import com.zjrs.zwnw.sxgl.blo.SxpzxxBLO;
import com.zjrs.zwnw.sxgl.bpo.SxpzxxBPO;
import com.zjrs.zwnw.sxgl.dto.*;
import com.zjrs.zwnw.sxgl.entity.SxpzxxMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SxpzxxBPOimpl extends BPOImpl implements SxpzxxBPO {
    private static final Logger LOG = LoggerFactory.getLogger(SxpzxxBPOimpl.class);
    @Resource
    private SxpzxxBLO sxpzxxBLO;
    @Resource
    SxpzxxMapper sxpzxxMapper;

    @Override
    public PageResult querySxList(SxpzxxQueryDTO dto, int page, int rows) {
        return this.sxpzxxBLO.querySxList(dto, page, rows);
    }

    @Override
    public Map<String, String> updateSxztByIds(SxpzxxQueryDTO dto) {
        return this.sxpzxxBLO.updateSxztByIds(dto);
    }

    @Override
    public SxpzxxXsDTO getSxpzxxById(SxpzxxXsQueryDTO dto) {
        return this.sxpzxxBLO.getSxpzxxById(dto);
    }

    @Override
    public PageResult getSxglclList(SxglclQueryDTO dto, int page, int rows) {
        return this.sxpzxxBLO.getSxglclList(dto, page, rows);
    }

    @Override
    public PageResult getSxWglclList(SxWglclQueryDTO dto, int page, int rows) {
        return this.sxpzxxBLO.getSxWglclList(dto, page, rows);
    }

    @Override
    public Map<String, String> addSxglclByIds(SxglclAddDTO dto) {
        return this.sxpzxxBLO.addSxglclByIds(dto);
    }

    @Override
    public void deleteSxglclByIds(SxglclDeleteDTO dto) {
        this.sxpzxxBLO.deleteSxglclByIds(dto);
    }

    @Override
    public Map<String, String> updateSxglcl(SdszzcxxDTO dto) {
        Map<String, String> resultMap = new HashMap<>();

        StringBuilder errMsg = new StringBuilder();
        if (StringUtils.isNotBlank(dto.getClsm())) {
            dto.setClsm(dto.getClsm().trim());
            if (getLength(dto.getClsm()) > 200) {
                errMsg.append("“材料说明”").append("内容超出长度限制，最多录入100个汉字或者200字符；");
            }
        }
        if (StringUtils.isBlank(dto.getYjfs())) {
            errMsg.append("原件份数不能为空。");
        } else {
            if (dto.getYjfs().getBytes().length > 3) {
                errMsg.append("“原件份数”").append("内容超出长度限制，最多录入3个字符；");
            }
        }
        if (StringUtils.isBlank(dto.getFyjfs())) {
            errMsg.append("复印件份数不能为空。");
        } else {
            if (dto.getFyjfs().getBytes().length > 3) {
                errMsg.append("“复印件份数”").append("内容超出长度限制，最多录入3个字符；");
            }
        }
        if (dto.getOrderno() == null) {
            errMsg.append("排序号不能为空。");
        } else {
            if (dto.getOrderno().toString().getBytes().length > 3) {
                errMsg.append("“排序号”").append("内容超出长度限制，最多录入3个字符；");
            }
        }
        if (StringUtils.isBlank(dto.getSfbsbz())) {
            errMsg.append("是否必要材料不能为空。");
        }
        if (errMsg.length() > 0) {
            resultMap.put("code", "1");
            resultMap.put("msg", errMsg.toString());
        } else {
            this.sxpzxxBLO.updateSxglcl(dto);
            resultMap.put("code", "0");
            resultMap.put("msg", "操作成功");
        }
        return resultMap;
    }

    @Override
    public PageResult getLchjList(SxgllcQueryDTO dto, int page, int rows) {

        //流程临时表有，直接返回
        int lctempcount = this.sxpzxxBLO.checkLcTemp(dto.getRsSxConfigLsh());
        if(lctempcount > 0){
            //从临时表取出返回
            return this.sxpzxxBLO.getSxlcpzList(dto.getRsSxConfigLsh(), page, rows);
        }

        return this.sxpzxxBLO.getLchjList(dto, page, rows);
    }

    @Override
    public Map<String, String> updateSxpzxxById(SxpzxxXsUpdateDTO dto) {
        Map<String, String> resultMap = new HashMap<>();

        StringBuilder errMsg = new StringBuilder();
        if (StringUtils.isBlank(dto.getSxlx())) {
            errMsg.append("事项类型不能为空。");
        }
        if (StringUtils.isBlank(dto.getSxlb())) {
            errMsg.append("主办科室不能为空。");
        }
        if (StringUtils.isBlank(dto.getYwzt())) {
            errMsg.append("业务主题不能为空。");
        }
        if (StringUtils.isBlank(dto.getBllx())) {
            errMsg.append("办理类型不能为空。");
        }
        if (StringUtils.isBlank(dto.getFdbjsx())) {
            errMsg.append("法定办结时限不能为空。");
        } else {
            dto.setFdbjsx(dto.getFdbjsx().trim());
            if (getLength(dto.getFdbjsx()) > 3) {
                errMsg.append("“法定办结时限”").append("内容超出长度限制，最多录入3个字符；");
            }
        }
        if (StringUtils.isBlank(dto.getFdbjsxdw())) {
            errMsg.append("法定办结时限单位不能为空。");
        }
        if (dto.getBlsx() == null) {
            errMsg.append("承诺办理时限不能为空。");
        } else {
            if (dto.getBlsx().toString().getBytes().length > 3) {
                errMsg.append("“承诺办理时限”").append("内容超出长度限制，最多录入3个字符；");
            }
        }
        if (StringUtils.isBlank(dto.getCnbjsxdw())) {
            errMsg.append("承诺办结时限单位不能为空。");
        }
        if (StringUtils.isBlank(dto.getDxccs())) {
            errMsg.append("到现场次数不能为空。");
        }
        if (StringUtils.isBlank(dto.getSfzcwlkd())) {
            errMsg.append("是否支持物流快递不能为空。");
        }
        if (StringUtils.isBlank(dto.getGr()) && StringUtils.isBlank(dto.getDw())) {
            errMsg.append("服务对象：个人/单位至少选择一项。");
        }
        if (StringUtils.isBlank(dto.getSlqd())) {
            errMsg.append("受理渠道不能为空。");
        }
        if (StringUtils.isBlank(dto.getSltj())) {
            errMsg.append("受理条件不能为空。");
        } else {
            dto.setSltj(dto.getSltj().trim());
            if (getLength(dto.getSltj()) > 4000) {
                errMsg.append("“受理条件”").append("内容超出长度限制，最多录入2000个汉字或4000个字符；");
            }
        }
        if (!StringUtils.isBlank(dto.getSltjxcx())) {
            dto.setSltjxcx(dto.getSltjxcx().trim());
            if (getLength(dto.getSltjxcx()) > 4000) {
                errMsg.append("“受理条件(小程序)”").append("内容超出长度限制，最多录入2000个汉字或4000个字符；");
            }
        }
        if (!StringUtils.isBlank(dto.getBz())) {
            dto.setBz(dto.getBz().trim());
            if (getLength(dto.getBz()) > 2000) {
                errMsg.append("“温馨提示”").append("内容超出长度限制，最多录入1000个汉字或2000个字符；");
            }
        }
        if (StringUtils.isNotBlank(dto.getSdyj())) {
            dto.setSdyj(dto.getSdyj().trim());
            if (getLength(dto.getSdyj()) > 4000) {
                errMsg.append("“设定依据”").append("内容超出长度限制，最多录入2000个汉字或4000个字符；");
            }
        }
        if(!"1".equals(dto.getSlqd())){
            if(StringUtils.isBlank(dto.getDsfxtblwz())){
                errMsg.append("网办系统办理网址不能为空。");
            }else {
                dto.setDsfxtblwz(dto.getDsfxtblwz().trim());
                if (getLength(dto.getDsfxtblwz()) > 300) {
                    errMsg.append("“网办系统办理网址”").append("内容超出长度限制，最多录入300个字符；");
                }
            }
            if(StringUtils.isBlank(dto.getDsfxtblsm())){
                errMsg.append("网办系统办理说明不能为空。");
            }else {
                dto.setDsfxtblsm(dto.getDsfxtblsm().trim());
                if (getLength(dto.getDsfxtblsm()) > 4000) {
                    errMsg.append("“网办系统办理说明”").append("内容超出长度限制，最多录入2000个汉字或4000个字符；");
                }
            }
        }
        if (errMsg.length() > 0) {
            resultMap.put("code", "1");
            resultMap.put("msg", errMsg.toString());
        } else {
            //处理事项编码,为空时，自动生成
            if(StringUtils.isBlank(dto.getSxbm())){
                SxpzxxLcpzDTO lcpzDTO = this.getLcmcById(dto.getRsSxConfigLsh(),dto.getSxlb());
                dto.setSxbm(lcpzDTO.getSxbm());
            }
            this.sxpzxxBLO.updateSxpzxxById(dto);
            resultMap.put("code", "0");
            resultMap.put("msg", "保存成功");
        }
        return resultMap;
    }

    @Override
    public SxglclListDTO getSxglcXx(SxglclXxQueryDTO dto) {
        return this.sxpzxxBLO.getSxglcXx(dto);
    }

    @Override
    public Map<String, String> checkNext(CheckDTO dto) {
        return this.sxpzxxBLO.checkNext(dto);
    }

    private int getLength(String str) {
        int length = 0;
        if (StringUtils.isNotBlank(str)) {
            try {
                length = str.trim().getBytes("GBK").length;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return length;
    }
    //检查事项编码，没有即自动生成
    public SxpzxxLcpzDTO getLcmcById(String id,String sxlb){
        LOG.info("根据主键查事项编码，没有即自动生成");
        SxpzxxLcpzQueryDTO sxdto = new SxpzxxLcpzQueryDTO();
        sxdto.setRsSxConfigLsh(id);
        SxpzxxLcpzDTO dto = this.sxpzxxBLO.getSxpzxxLcpzById(sxdto);
        Map<String,String> rMap = new HashMap<String,String>();

        if(StringUtils.isBlank(dto.getSxbm())){//事项编码为空，自动生成
            if(StringUtils.isBlank(sxlb)){
                sxlb = dto.getSxlb();
            }
            String presxbm=sxlb;
            //根据事项编码前缀，找最大值加1生成新编码，市级综合规则科与事业单位科事项编码前缀与事项类别不一致，做转换
            if("44080001".equals(sxlb)){
                presxbm="44080010";
            }
            if("44080003".equals(sxlb)){
                presxbm="44080030";
            }

            //根据事项编码前缀，找事项编码最大值
            String maxsxbm = this.sxpzxxBLO.getMaxSxbm(presxbm);
            String newsxbm = "";
            if(maxsxbm == null){
                newsxbm = presxbm +"01";
            }else{
                newsxbm = String.valueOf(Long.parseLong(maxsxbm)+1);
            }
            LOG.info("事项编码为空，自动生成："+newsxbm);

            //更新事项编码
            sxdto.setSxbm(newsxbm);
            sxdto.setProcessdefname(newsxbm);        //事项编码为空时，流程定义名改为与事项编码一致
            this.sxpzxxBLO.updateSxbmById(sxdto);

            LOG.info("事项编码为空，自动生成编码，流程名称："+newsxbm);
            dto.setProcessdefname(newsxbm);
            dto.setSxbm(newsxbm);
            return dto;
        }
        LOG.info("事项编码已存在,事项编码："+dto.getSxbm()+",流程名称："+dto.getProcessdefname());
        return dto;
    }
    @Override
    public boolean checkProcessInstance(String id){
        return this.sxpzxxBLO.checkProcessInstance(id);
    }
    @Override
    public PageResult getSxlcpzList(SxpzxxLcpzQueryDTO dto, int page, int rows) {

        this.createLcpzTemp(dto.getRsSxConfigLsh());

        //从临时表取出返回
        return this.sxpzxxBLO.getSxlcpzList(dto.getRsSxConfigLsh(), page, rows);
    }

    private void createLcpzTemp(String id){
        //流程临时表有，直接返回
        int lctempcount = this.sxpzxxBLO.checkLcTemp(id);
        LOG.info("查流程临时表，记录数："+lctempcount);
        //流程临时表没有
        if(lctempcount == 0){
            this.gobackLcpz(id);
        }
    }

    //新增环节
    @Override
    public Map<String, String> addHj(SxpzxxLcpzAddHjQueryDTO dto){
        Map<String, String> resultMap = new HashMap<String, String>();
        int i =this.sxpzxxBLO.checkLcExistKyls(dto.getProcessdefid());
        if(i == 0){//还不存在科员受理环节
            //增加科员受理环节
            LOG.info("新增环节,还不存在科员受理环节");
            this.sxpzxxBLO.addHjKysl(dto.getProcessdefid());
            resultMap.put("isAddKyls","1");

        }else{
            LOG.info("新增环节,已存在科员受理环节");
            resultMap.put("isAddKyls","0");
        }
        return resultMap;
    }

    //保存环节
    @Override
    public Map<String, String> saveHj(SxpzxxLcpzSaveHjDTO dto){
        return this.sxpzxxBLO.saveHj(dto);

    }
    //删除环节
    @Override
    public void delHj(SxpzxxLcpzDelHjDTO dto){
        this.sxpzxxBLO.delHj(dto);

    }
    //环节设置列表
    @Override
    public List<SxpzxxLcpzSetListDTO> getLcpzSetList(SxpzxxLcpzSetDTO dto){
        return this.sxpzxxBLO.getLcpzSetList(dto);
    }
    //保存环节设置列表
    @Override
    public Map<String, String> saveSetHj(SxpzxxLcpzSetListSaveDTO dto){
        return this.sxpzxxBLO.saveSetHj(dto);
    }
    //还原流程
    @Override
    public void gobackLcpz(String rsSxConfigLsh){
        //查流程正式表
        int zslccount = this.sxpzxxBLO.checkZslc(rsSxConfigLsh);
        LOG.info("查流程正式表，记录数："+zslccount);
        //获取流程定义名称和事项编码
        SxpzxxLcpzDTO lcpzDTO = this.getLcmcById(rsSxConfigLsh,"");
        if (zslccount == 0) {//正式流程还不存在
            //初始化流程
            LOG.info("正式流程不存在,初始化流程");
            this.sxpzxxBLO.initLcTemp(lcpzDTO);

        }else{//正式流程已存在
            //转换到临时表
            LOG.info("正式流程已存在,转换到临时表");
            SxpzxxLcpzQueryDTO dto = new SxpzxxLcpzQueryDTO();
            dto.setRsSxConfigLsh(rsSxConfigLsh);
            dto.setProcessdefname(lcpzDTO.getProcessdefname());
            this.sxpzxxBLO.changeLc2Temp(dto);

        }
    }

    //确认流程
    @Override
    public Map<String, String> confirmLcpz(SxpzxxLcpzConfirmDTO dto){
        return this.sxpzxxBLO.confirmLcpz(dto);
    }
    //环节名称动态字典
    @Override
    public List<HjmcDictDTO> getHjmcDict(){
        return sxpzxxBLO.getHjmcDict();
    }

    @Override
    public Map<String, List> getLcpzLct(SxpzxxLcpzGetLctDTO dto) {
        //流程临时表是否存在，没有即生成
        String id = this.sxpzxxBLO.getRssxconfigIdByProcessdefid(dto.getProcessdefid());
        if(!StringUtils.isBlank(id)){
            this.createLcpzTemp(id);
        }
        return sxpzxxBLO.getLcpzLct(dto);
    }
    //获取事项配置附件list
    @Override
    public PageResult getFjybList(SxpzxxFjybQueryDTO dto, Integer pagenum, Integer pagesize){
        return this.sxpzxxBLO.getSxpzxxFjybList(dto,pagenum,pagesize);
    }
    //保存事项配置附件
    public Map<String, String> saveFjyb(SxpzxxFjybSaveDTO dto){
        return this.sxpzxxBLO.saveFjyb(dto);
    }
    //删除事项配置附件
    public void delFjybByIds(SxpzxxFjybDelDTO dto){
        this.sxpzxxBLO.delFjybByIds(dto);
    }
    //批量修改领导信息
    public void saveBatchLdxx(SxpzxxBatchUpdateLdxxDTO dto){
        this.sxpzxxBLO.saveBatchLdxx(dto);
    }

    @Override
    public List<HjmcDictDTO> getSysx(String sxbm) {
        List<HjmcDictDTO> dictDTOS = new ArrayList<>();
        //取关联事项
        SxpzxxXsDTO sxpzxxXsDTO = this.sxpzxxMapper.getSxpzxxBySxbm(sxbm);

        if(sxpzxxXsDTO == null){
            return dictDTOS;
        }
        //不为空时，组装字典
        String glsx = sxpzxxXsDTO.getGlsx();
        if(glsx.contains(",")){
            String [] glsxArr = glsx.split(",");
            for(String sxbmstr : glsxArr){
                SxpzxxXsDTO dto = this.sxpzxxMapper.getSxpzxxBySxbm(sxbmstr);
                if(dto != null){
                    HjmcDictDTO hjmcDictDTO = new HjmcDictDTO();
                    hjmcDictDTO.setCode(sxbmstr);
                    hjmcDictDTO.setDetail(dto.getSxmc());
                    dictDTOS.add(hjmcDictDTO);
                }
            }
        }else{
            SxpzxxXsDTO dto = this.sxpzxxMapper.getSxpzxxBySxbm(glsx);
            if(dto != null){
                HjmcDictDTO hjmcDictDTO = new HjmcDictDTO();
                hjmcDictDTO.setCode(glsx);
                hjmcDictDTO.setDetail(dto.getSxmc());
                dictDTOS.add(hjmcDictDTO);
            }
        }
        return dictDTOS;
    }

}
