package com.zcloud.service.eightwork.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zcloud.entity.Page;
import com.zcloud.entity.PageData;
import com.zcloud.mapper.datasource.eightwork.*;
import com.zcloud.service.eightwork.HighworkService;
import com.zcloud.service.eightwork.HoistingService;
import com.zcloud.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

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

/**
 * @author fangjiakai
 * @date 2024/01/17 11:30
 */
@Service
@Transactional //开启事物
public class HoistingServiceImpl implements HoistingService {
    @Autowired
    private HighworkService highworkService;
    @Autowired
    private HoistingMapper hoistingMapper;
    @Autowired
    private EightWorkTaskFlowMapper eightWorkTaskFlowMapper;
    @Autowired
    private EightWorkFlowLogMapper eightWorkFlowLogMapper;
    @Autowired
    private HoistingSignMapper hoistingSignMapper;
    @Autowired
    private HoistingToMeasuresMapper hoistingToMeasuresMapper;
    @Autowired
    private EightWorkVideoManagerMapper eightworkvideomanagerMapper;
    @Autowired
    private Smb smb;
    @Autowired
    private SendMessageUtil sendMessageUtil;

    private final String primary_key = "HOISTING_ID";
    private final String work_type = "HOISTING";

    @Override
    @Transactional
    public void save(PageData pd) throws Exception {
        PageData pd2 = new PageData();
        Calendar calendar = Calendar.getInstance();
        DecimalFormat dft = new DecimalFormat("00");
        int year = calendar.get(Calendar.YEAR);
        String month = dft.format(calendar.get(Calendar.MONTH) + 1);
        String day = dft.format(calendar.get(Calendar.DAY_OF_MONTH));
        pd2.put("CREATDATE", year + "-" + month + "-" + day);
        pd2.put("CORPINFO_ID", pd.get("CORPINFO_ID"));
        pd2 = hoistingMapper.getCode(pd2);    //根据ID读取
        String code = "DZ" + year + month + day + dft.format((Integer.parseInt(pd2.get("code").toString()) + 1));
        pd.put("CHECK_NO", code);
        pd.put(primary_key, UuidUtil.get32UUID());    //主键
        pd.put("CREATTIME", DateUtil.date2Str(new Date()));    //添加时间
        pd.put("OPERATTIME", DateUtil.date2Str(new Date()));    //修改时间
        pd.put("ISDELETE", "0");    //是否删除 1-是  0-否
        hoistingMapper.save(pd);

        if (pd.get("APPLY_STATUS").equals("1")) {
            if (Tools.notEmpty(pd.getString("SPECIAL_WORK"))) {
                String[] specialWorks = pd.getString("SPECIAL_WORK").split(",");
                if (specialWorks.length != 0) {
                    for (int i = 0; i < specialWorks.length; i++) {
                        String[] workNameANo = specialWorks[i].split(" ");
                        highworkService.changeOtherWorkCard(workNameANo, pd.getString("CORPINFO_ID"), "吊装作业 " + pd.getString("CHECK_NO"));
                    }
                }
            }
            PageData flow = getStep(pd.get("TASK_ID"), "1");
            saveLog(pd, pd.getString("CREATOR"), "1");
            saveNextSigner(pd, flow);
            if (Tools.notEmpty(pd.getString("PLS_ID"))) {
                setPosition(pd);
            }

        }
    }

    @Override
    @Transactional
    public void edit(PageData pd) throws Exception {
        pd.put("OPERATTIME", DateUtil.date2Str(new Date()));    //修改时间
        hoistingMapper.edit(pd);

        if (pd.get("APPLY_STATUS").equals("1")) {
            pd.put("STEP_ID", 1);
            hoistingMapper.editStep(pd);
            if (Tools.notEmpty(pd.getString("SPECIAL_WORK"))) {
                String[] specialWorks = pd.getString("SPECIAL_WORK").split(",");
                if (specialWorks.length != 0) {
                    for (int i = 0; i < specialWorks.length; i++) {
                        String[] workNameANo = specialWorks[i].split(" ");
                        highworkService.changeOtherWorkCard(workNameANo, pd.getString("CORPINFO_ID"), "吊装作业 " + pd.getString("CHECK_NO"));
                    }
                }
            }
            PageData flow = getStep(pd.get("TASK_ID"), "1");
            saveLog(pd, pd.getString("CREATOR"), "1");
            saveNextSigner(pd, flow);
            if (Tools.notEmpty(pd.getString("PLS_ID"))) {
                setPosition(pd);
            }

        }
    }

    @Override
    public void delete(PageData pd) throws Exception {
        hoistingMapper.delete(pd);
    }

    @Override
    public List<PageData> list(Page page) throws Exception {
        return hoistingMapper.datalistPage(page);
    }


    /*
     * 下一步
     */
    @Override
    @Transactional
    public void nextStep(PageData pd, MultipartFile[] files) throws Exception {
        PageData work = this.findById(pd);
        work.putAll(pd);
        List<String> filePaths = new ArrayList<>();
        for (int i = 0; i < files.length; i++) {
            //保存签名文件
            String ffile = DateUtil.getDays();
            String fileName = UuidUtil.get32UUID() + files[i].getOriginalFilename().substring(files[i].getOriginalFilename().lastIndexOf("."));
            smb.sshSftp(files[i], fileName, Const.FILEPATHFILE + work.getString("CORPINFO_ID") + "/" + ffile);
            filePaths.add(Const.FILEPATHFILE + work.getString("CORPINFO_ID") + "/" + ffile + "/" + fileName);
        }
        PageData flow = getStep(work.get("TASK_ID"), work.get("STEP_ID"));
        work.put("STEP_ID", flow.get("NEXT_STEP_ID"));
        hoistingMapper.editVideo(work);

        //保存签名信息
        PageData sign = new PageData();
        sign.put(primary_key, work.get(primary_key));
        sign.put("STEP_ID", work.get("STEP_ID"));
        sign.put("SIGN_USER_ID", work.get("USER_ID"));
        sign.put("SIGN_TIME", work.getString("SIGNTIME"));
        sign.put("SIGN_PATH", String.join(",", filePaths));
        sign.put("DESCR", work.get("DESCR"));

        hoistingSignMapper.edit(sign);

        if (work.get("MEASURES") != null && !work.get("MEASURES").equals("")) { //安全措施确认步骤
            saveMeasures(work);
        }

        List<PageData> unsignedList = hoistingSignMapper.checkUnsigned(sign);//当前步骤未签名人列表
        if ((unsignedList == null || unsignedList.size() == 0) && pd.getString("APPLY_STATUS").equals("1")) {//如果没有未签人 则跳转下一步
            hoistingMapper.editStep(work);
            PageData currentflow = getStep(work.get("TASK_ID"), work.get("STEP_ID"));

            //保存日志
            saveLog(work, work.getString("USER_ID"), "1");

            if ("99".equals(currentflow.getString("NEXT_STEP_ID"))) {
                eightworkvideomanagerMapper.editStatus(work);
                sendMessageForFinished(work.getString("CORPINFO_ID"), work.getString("CREATOR"), "EIGHTWORK_REJECT", work.getString("CHECK_NO"));

                return;
            }
            if (work.get("PREPARERS") != null && !work.get("PREPARERS").equals("")) { //如果是设置安全措施确认人步骤
                savePreparers(work, currentflow);
            }
            saveNextSigner(work, currentflow);
        } else if (pd.getString("APPLY_STATUS").equals("-1")) {
            //保存日志
            saveLog(work, work.getString("USER_ID"), "-1");
            eightworkvideomanagerMapper.editStatus(work);

            work.put("STEP_ID", -1);
            hoistingMapper.editStep(work);
            sendMessageForFinished(work.getString("CORPINFO_ID"), work.getString("CREATOR"), "EIGHTWORK_REJECT", work.getString("CHECK_NO"));

        }
        // 作业 监护人停止
        else if ("-3".equals(pd.getString("APPLY_STATUS"))) {
            //保存日志
            saveLog(work, work.getString("USER_ID"), "-3");
            eightworkvideomanagerMapper.editStatus(work);
            work.put("STEP_ID", -3);
            hoistingMapper.editStep(work);
            sendMessageForFinished(work.getString("CORPINFO_ID"), work.getString("CREATOR"), "EIGHTWORK_STOP", work.getString("CHECK_NO"));
        }
    }

    @Override
    public PageData findById(PageData pd) throws Exception {
        PageData pageData = hoistingMapper.findById(pd);
        return pageData;
    }

    @Override
    public PageData listSignFinished(PageData pd) throws Exception {
        Map<String, List<PageData>> rmap = new HashMap<>();
        List<PageData> varList = hoistingSignMapper.listAll(pd);
        if (varList != null && !varList.isEmpty()) {
            varList.stream().forEach(item -> {
                PageData sign = new PageData();
                sign.put("SIGN_PATH", item.getString("SIGN_PATH").split(","));
                sign.put("SIGN_TIME", item.getString("SIGN_TIME").split(","));

                sign.put("DESCR", item.getString("DESCR") != null ? item.getString("DESCR") : "无");
                if (rmap.containsKey(item.getString("CODE"))) {
                    rmap.get(item.getString("CODE")).add(sign);
                } else {
                    List<PageData> signs = new ArrayList<>();
                    signs.add(sign);
                    rmap.put(item.getString("CODE"), signs);
                }
            });
        }
        PageData rpd = new PageData();
        if (rmap != null && !rmap.isEmpty()) {
            rpd.putAll(rmap);
        }
        return rpd;
    }

    @Override
    public PageData checkWorkCount(PageData pd) {
        PageData rpd = new PageData();
        List<PageData> varList = hoistingMapper.checkWorkCount(pd);

        if (varList != null && !varList.isEmpty()) {
            Map<String, String> newMap = varList.stream()
                    .collect(Collectors.toMap(map -> map.getString("CODE"), map -> map.getString("COUNT")));

            rpd.putAll(newMap);
        }
        return rpd;
    }

    @Override
    public List<PageData> listAllMeasures() throws Exception {
        return hoistingMapper.listAllMeasures();

    }

    @Override
    public List<PageData> listAllMeasuresForSign(PageData pd) throws Exception {
        return hoistingToMeasuresMapper.listAllMeasuresForSign(pd);

    }

    @Override
    public List<PageData> listSignFinishMeasures(PageData pd) throws Exception {
        return hoistingToMeasuresMapper.listSignFinishMeasures(pd);
    }


    @Override
    public List<PageData> getFlowList(PageData pd) throws Exception {
        pd = findById(pd);
        return hoistingMapper.getFlowList(pd);
    }

    @Override
    public ReturnMap getMapList() throws Exception {
        ReturnMap returnMap = new ReturnMap();
        PageData pd = new PageData();
        pd.put("CORPINFO_ID", Jurisdiction.getCORPINFO_ID());
        returnMap.put("varList", hoistingMapper.getMapList(pd));
        return returnMap;
    }

    private void saveNextSigner(PageData pd, PageData flow) throws Exception {

        pd.put("STEP_ID", flow.get("NEXT_STEP_ID"));

        if (pd.get(flow.get("NEXT_ACTOR_FIELD")) == null || pd.get(flow.get("NEXT_ACTOR_FIELD")).equals("")) {
            return;
        }
        //提前保存下一步签字人
        List<PageData> signers = new ArrayList<>();
        PageData signer = new PageData();
        signer.put("HOISTING_SIGN_ID", UuidUtil.get32UUID()); // 主键
        signer.put(primary_key, pd.get(primary_key));
        signer.put("CORPINFO_ID", pd.get("CORPINFO_ID"));
        signer.put("SIGN_USER_ID", pd.get(flow.get("NEXT_ACTOR_FIELD")));
        signer.put("STEP_ID", flow.get("NEXT_STEP_ID"));
        signers.add(signer);
        hoistingSignMapper.saveBatch(signers);
        sendMessageForNext(pd.getString("CORPINFO_ID"), pd.getString(flow.get("NEXT_ACTOR_FIELD")), pd.getString("CHECK_NO"), flow.getString("NEXT_STEP_NAME"));

    }

    private void saveMeasures(PageData pd) {
        List<JSONObject> list = (List<JSONObject>) JSON.parse(pd.get("MEASURES").toString());
        for (JSONObject json : list) {
            PageData measure = new PageData();
            measure.put("HOISTINGTOMEASURES_ID", json.get("HOISTINGTOMEASURES_ID"));
            measure.put("STATUS", json.get("STATUS"));
            measure.put("SIGN_PATH", json.get("SIGN_PATH"));
            measure.put("SIGN_TIME", json.get("SIGN_TIME"));
            measure.put("ANSWER1", json.get("ANSWER1"));
            measure.put("IMG_PATH", json.get("IMG_PATH"));
            hoistingToMeasuresMapper.edit(measure);
        }
    }

    private void savePreparers(PageData pd, PageData flow) {
        List<PageData> signers = new ArrayList<>();
        List<JSONObject> list = (List<JSONObject>) JSON.parse(pd.get("PREPARERS").toString());
        for (JSONObject json : list) {
            PageData preparer = new PageData();
            preparer.put("HOISTINGTOMEASURES_ID", UuidUtil.get32UUID()); // 主键
            preparer.put("HOISTING_ID", pd.get("HOISTING_ID"));
            preparer.put("BUS_HOISTING_MEASURES_ID", json.get("BUS_HOISTING_MEASURES_ID"));
            preparer.put("CONFIRM_ID", json.get("USER_ID"));
            signers.add(preparer);
        }
        if (signers.size() > 0) {
            hoistingToMeasuresMapper.saveBatch(signers);

            //获取所有需要签名人
            List<String> fieldList = signers.stream()
                    .map(map -> map.getString("CONFIRM_ID"))
                    .collect(Collectors.toList());
            Set<String> fieldSet = new HashSet<>(fieldList); //去重

            List<String> uniqueList = new ArrayList<>(fieldSet);
            List<PageData> nextSigners = new ArrayList<>();
            uniqueList.forEach(item -> { // 保存下一步需要签名的人
                PageData signer = new PageData();
                signer.put("HOISTING_SIGN_ID", UuidUtil.get32UUID()); // 主键
                signer.put(primary_key, pd.get(primary_key));
                signer.put("CORPINFO_ID", pd.get("CORPINFO_ID"));
                signer.put("SIGN_USER_ID", item);
                signer.put("STEP_ID", flow.get("NEXT_STEP_ID"));
                nextSigners.add(signer);
                try {
                    sendMessageForNext(pd.getString("CORPINFO_ID"), item, pd.getString("CHECK_NO"), flow.getString("NEXT_STEP_NAME"));
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });

            hoistingSignMapper.saveBatch(nextSigners);
        }
    }

    private PageData getStep(Object TASK_ID, Object STEP_ID) throws Exception {
        PageData flow = new PageData();
        flow.put("TASK_ID", TASK_ID);
        flow.put("STEP_ID", STEP_ID);
        flow = eightWorkTaskFlowMapper.getStep(flow);
        return flow;
    }

    private void saveLog(PageData pd, String act_user, String status) throws Exception {
        PageData log = new PageData();
        log.put("LOG_ID", UuidUtil.get32UUID());
        log.put("WORK_ID", pd.get(primary_key));
        log.put("TASK_ID", pd.get("TASK_ID"));
        log.put("STEP_ID", pd.get("STEP_ID"));
        log.put("CORPINFO_ID", pd.get("CORPINFO_ID"));
        log.put("CHECK_NO", pd.get("CHECK_NO"));
        log.put("ACT_USER", act_user);
        log.put("ACT_TIME", DateUtil.date2Str(new Date()));
        log.put("STATUS", status);
        log.put("WORK_TYPE", work_type);
        eightWorkFlowLogMapper.save(log);
    }


    private void setPosition(PageData pd) throws Exception {
        JSONObject body = PLSUtil.getRyRegionInfo(pd.getString("CORPINFO_ID"), Integer.parseInt(pd.getString("PLS_ID")));
        List pointList = (List) ((Map) body.get("data")).get("list");
        List<String> positions = PLSUtil.getRandomPointInPolygon(pointList);
        pd.put("WORK_POSITION", String.join(",", positions));
        hoistingMapper.setPosition(pd);
    }

    private void sendMessageForNext(String corpinfo_id, String userId, String number, String flow_name) throws Exception {
        PageData mes = new PageData();
        mes.put("RECEIVER_ID", userId);// 收信人userid
        mes.put("templateCode", "EIGHTWORK_REMINDER");// 短信模板编码
        mes.put("CORPINFO_ID", corpinfo_id);// 企业id

        // 参数集合
        List<PageData> paramsList = new ArrayList<PageData>();
        // 第1个参数
        PageData params1 = new PageData();
        params1.put("name", "number");// 存入短信模板中的参数名称
        params1.put("value", number);// 存入上面参数名称所传递的值
        paramsList.add(params1);

        PageData params2 = new PageData();
        params2.put("name", "type");// 存入短信模板中的参数名称
        params2.put("value", "动火作业");// 存入上面参数名称所传递的值
        paramsList.add(params2);

        PageData params3 = new PageData();
        params3.put("name", "flow");// 存入短信模板中的参数名称
        params3.put("value", flow_name);// 存入上面参数名称所传递的值
        paramsList.add(params3);
        try {
            sendMessageUtil.sendMessages(mes, paramsList);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private void sendMessageForFinished(String corpinfo_id, String userId, String template, String number) throws Exception {
        PageData mes = new PageData();
        mes.put("RECEIVER_ID", userId);// 收信人userid
        mes.put("templateCode", template);// 短信模板编码
        mes.put("CORPINFO_ID", corpinfo_id);// 企业id

        // 参数集合
        List<PageData> paramsList = new ArrayList<PageData>();
        // 第1个参数
        PageData params1 = new PageData();
        params1.put("name", "number");// 存入短信模板中的参数名称
        params1.put("value", number);// 存入上面参数名称所传递的值
        paramsList.add(params1);

        PageData params2 = new PageData();
        params2.put("name", "type");// 存入短信模板中的参数名称
        params2.put("value", "动火作业");// 存入上面参数名称所传递的值
        paramsList.add(params2);

        try {
            sendMessageUtil.sendMessages(mes, paramsList);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
