package com.engine.recruit.service.impl;

import cn.hutool.core.convert.Convert;
import com.engine.core.impl.Service;
import com.engine.recruit.conn.ApplicantCommonInfo;
import com.engine.recruit.conn.RecruitDataMap;
import com.engine.recruit.conn.RecruitRecordSet;
import com.engine.recruit.entity.recruitflow.po.*;
import com.engine.recruit.enums.ApplicationStatusEnum;
import com.engine.recruit.exception.CustomizeRunTimeException;
import com.engine.recruit.service.RecruitFlowService;
import com.engine.recruit.util.RecruitFlowUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import weaver.conn.RecordSet;
import weaver.general.Util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author:dxfeng
 * @createTime: 2023/09/22
 * @version: 1.0
 */
public class RecruitFlowServiceImpl extends Service implements RecruitFlowService {
    @Override
    public Map<String, Object> getButtonList(Map<String, Object> param) {
        Map<String, Object> returnMap = new HashMap<>();
        String billId = Util.null2String(param.get("billId"));

        // 招聘阶段ID
        String stageId = "";
        // 招聘流程ID
        int recruitFlowId = -1;
        String zt = "";

        RecordSet rs = new RecordSet();
        rs.executeQuery("select zplc,zpjd,zt from uf_jcl_yppc where id = ?", billId);
        if (rs.next()) {
            recruitFlowId = rs.getInt("zplc");
            stageId = rs.getString("zpjd");
            zt = rs.getString("zt");
        }
        if (StringUtils.isBlank(zt) || ApplicationStatusEnum.DISTRIBUTION.getValue().equals(zt)) {
            returnMap.put("redirect", true);
            int modeId = ApplicantCommonInfo.getModeIdByTableName("uf_jcl_yppc");
            String url = "/spa/cube/index.html#/main/cube/card?type=0&modeId=" + modeId + "&billid=" + billId + "&isSimpleResume=true";
            returnMap.put("url", url);
            return returnMap;
        }
        boolean isCandidate = zt.equals(ApplicationStatusEnum.CANDIDATE.getValue());
        List<String> filterButton = new ArrayList<>();
        filterButton.add("转推其他职位");
        filterButton.add("加入黑名单");
        filterButton.add("添加备注");
        if (-1 == recruitFlowId) {
            throw new CustomizeRunTimeException("未设置对应招聘流程");
        }


        if (StringUtils.isBlank(stageId)) {
            // 查询开始环节
            rs.executeQuery("select id from uf_jcl_zpjdsz where zplc = ? and hj = 0", recruitFlowId);
            if (rs.next()) {
                stageId = rs.getString("id");
            }
            if (StringUtils.isBlank(stageId)) {
                throw new RuntimeException("未找到对应招聘阶段");
            }
        }
        rs.executeQuery("select a.id,b.anmc,a.zdyxsmc as buttonName, a.tzymbt as tabName, a.tzymdz as tabLink, a.zssx as orderNum, b.anbs as buttonKey, b.andz as buttonType from uf_jcl_zpjdsz_dt1 a inner join uf_jcl_lcczan b on a.czan = b.id where a.sfqy = 0 and mainid = ? order by zssx", stageId);

        List<RecruitButton> buttonList = new ArrayList<>();
        List<RecruitTabPo> tabList = new ArrayList<>();
        while (rs.next()) {
            String anmc = rs.getString("anmc");
            if (!isCandidate && !filterButton.contains(anmc)) {
                // 非候选中，隐藏按钮
                continue;
            }
            buttonList.add(RecruitButton.builder()
                    .key(rs.getString("id"))
                    .buttonName(rs.getString("buttonName"))
                    .buttonKey(rs.getString("buttonKey"))
                    .tabName(rs.getString("tabName"))
                    .tabLink(RecruitFlowUtil.replaceURL(rs.getString("tabLink"), billId))
                    .buttonType(rs.getString("buttonType"))
                    .orderNum(rs.getInt("orderNum"))
                    .build());
        }

        rs.executeQuery("select ymbt as title,ymdz as url,zssx as orderNum from uf_jcl_zpjdsz_dt2 where mainid = ? order by orderNum", stageId);
        int tabIndex = 0;
        while (rs.next()) {
            tabList.add(RecruitTabPo.builder()
                    .key(String.valueOf(tabIndex))
                    .viewcondition(String.valueOf(tabIndex))
                    .title(rs.getString("title"))
                    .url(RecruitFlowUtil.replaceURL(rs.getString("url"), billId))
                    .billId(billId)
                    .build());
            tabIndex++;
        }


        // 当前阶段所有按钮信息
        returnMap.put("buttonList", buttonList);
        returnMap.put("tabList", tabList);
        return returnMap;
    }

    @Override
    public Map<String, Object> getRecruitStepList(Map<String, Object> param) {
        Map<String, Object> returnMap = new HashMap<>();

        String billId = Util.null2String(param.get("billId"));
        // 招聘阶段ID
        String stageId = "";
        int currentStageId = 0;
        // 招聘流程ID
        int recruitFlowId = -1;
        RecordSet rs = new RecordSet();
        rs.executeQuery("select zplc,zpjd from uf_jcl_yppc where id = ?", billId);
        if (rs.next()) {
            recruitFlowId = rs.getInt("zplc");
            stageId = rs.getString("zpjd");
        }
        if (-1 == recruitFlowId) {
            throw new CustomizeRunTimeException("未设置对应招聘流程");
        }
        rs.executeQuery("select id,jdmc from uf_jcl_zpjdsz where sfqy = 0 and zplc = ? order by hj,zssx", recruitFlowId);
        int stepIndex = 0;
        List<RecruitStepPo> stepList = new ArrayList<>();
        while (rs.next()) {
            String id = rs.getString("id");
            if (stageId.equals(id)) {
                currentStageId = stepIndex;
            }
            stepList.add(RecruitStepPo.builder().key(stepIndex).description(rs.getString("jdmc")).build());
            stepIndex++;
        }
        if ("-1".equals(stageId)) {
            currentStageId = stepList.size();
        }

        returnMap.put("stepList", stepList);
        returnMap.put("currentStageId", currentStageId);
        return returnMap;
    }

    @Override
    public Map<String, Object> syncRecruitStepInfo(Map<String, Object> param) {
        String stepId = Util.null2String(param.get("stepId"));
        String recruitFlowId = Util.null2String(param.get("recruitFlowId"));
        String checkedValue = Util.null2String(param.get("checkedValue"));

        if (StringUtils.isBlank(stepId)) {
            throw new CustomizeRunTimeException("未获取到所选招聘阶段,请刷新后重试");
        }
        if (StringUtils.isBlank(recruitFlowId)) {
            throw new CustomizeRunTimeException("同步流程为空，请选择同步流程");
        }
        if (StringUtils.isBlank(checkedValue)) {
            throw new CustomizeRunTimeException("请选择同步选项");
        }

        // 判断该流程是否有该阶段，没有该阶段的不做操作
        String flowStepId = getFlowStepId(stepId, recruitFlowId);
        if (StringUtils.isBlank(flowStepId)) {
            throw new CustomizeRunTimeException("所选流程不具备当前招聘阶段，同步失败");
        }


        switch (checkedValue) {
            case "syncAdd":
                syncAdd(stepId, flowStepId);
                break;
            case "syncOrder":
                syncOrder(stepId, flowStepId);
                break;
            case "syncAll":
                syncAll(stepId, flowStepId);
                break;
            case "syncTab":
                syncTab(stepId, flowStepId);
                break;
            default:
                throw new CustomizeRunTimeException("未识别的同步方式");
        }
        return null;
    }

    /**
     * 同步新增操作
     * 直接将缺失的操作按钮追加在原有按钮后方
     *
     * @param stepId
     * @param flowStepId
     */
    private void syncAdd(String stepId, String flowStepId) {
        List<RecruitStepDt1> stepDt1List = getStepDt1List(stepId);
        List<RecruitStepDt1> flowStepDt1List = getStepDt1List(flowStepId);

        // 比较差异,只保留flowStepDt1List中没有的元素
        List<RecruitStepDt1> result = stepDt1List.stream()
                .filter(item -> !flowStepDt1List.contains(item))
                .collect(Collectors.toList());

        // 元素追加
        Integer order = 0;
        if (CollectionUtils.isNotEmpty(flowStepDt1List)) {
            String zssx = flowStepDt1List.get(flowStepDt1List.size() - 1).getZssx();
            if (StringUtils.isNotBlank(zssx)) {
                order = Convert.toInt(zssx);
            }
        }

        for (RecruitStepDt1 stepDt1 : result) {
            order += 10;
            RecruitDataMap<Object> dataMap = new RecruitDataMap<>();
            dataMap.put("mainid", flowStepId);
            dataMap.put("czan", stepDt1.getCzan());
            dataMap.put("zdyxsmc", stepDt1.getZdyxsmc());
            dataMap.put("tzymdz", stepDt1.getTzymdz());
            dataMap.put("sfqy", stepDt1.getSfqy());
            dataMap.put("tzymbt", stepDt1.getTzymbt());
            dataMap.put("zssx", order.toString());
            RecruitRecordSet.insertData(dataMap, "uf_jcl_zpjdsz_dt1");
        }
    }

    /**
     * 同步操作顺序
     * 比较差异、按顺序插空进入
     *
     * @param stepId
     * @param flowStepId
     */
    private void syncOrder(String stepId, String flowStepId) {
        List<RecruitStepDt1> flowStepDt1List = getStepDt1List(flowStepId);
        List<RecruitStepDt1> stepDt1List = getStepDt1List(stepId);

        // 只保留stepDt1List中相同的元素
        stepDt1List.retainAll(flowStepDt1List);
        Map<RecruitStepDt1, String> collect = flowStepDt1List.stream().collect(Collectors.toMap(item -> item, RecruitStepDt1::getId, (k1, k2) -> k1));

        int index = 0;
        for (int i = 0; i < flowStepDt1List.size(); i++) {
            RecruitStepDt1 character = flowStepDt1List.get(i);
            if (stepDt1List.contains(character)) {
                RecruitStepDt1 remove = stepDt1List.get(index++);
                String s = collect.get(remove);
                remove.setId(s);
                flowStepDt1List.set(i, remove);
            }
        }

        // 调整展示顺序
        int order = 0;
        for (RecruitStepDt1 stepDt1 : flowStepDt1List) {
            RecruitDataMap<Object> dataMap = new RecruitDataMap<>();
            dataMap.put("zssx", order += 10);
            dataMap.put("id", stepDt1.getId());
            RecruitRecordSet.updateDataById(dataMap, "uf_jcl_zpjdsz_dt1");
        }
    }

    /**
     * 同步所有操作（覆盖替换）
     *
     * @param stepId
     * @param flowStepId
     */
    private void syncAll(String stepId, String flowStepId) {
        List<RecruitStepDt1> stepDt1List = getStepDt1List(stepId);

        // 删除原有的数据
        String deleteSql = "delete from uf_jcl_zpjdsz_dt1 where mainid = " + flowStepId;
        RecruitRecordSet.deleteData(deleteSql);
        for (RecruitStepDt1 stepDt1 : stepDt1List) {
            RecruitDataMap<Object> dataMap = new RecruitDataMap<>();
            dataMap.put("mainid", flowStepId);
            dataMap.put("czan", stepDt1.getCzan());
            dataMap.put("zdyxsmc", stepDt1.getZdyxsmc());
            dataMap.put("tzymdz", stepDt1.getTzymdz());
            dataMap.put("sfqy", stepDt1.getSfqy());
            dataMap.put("tzymbt", stepDt1.getTzymbt());
            dataMap.put("zssx", stepDt1.getZssx());
            RecruitRecordSet.insertData(dataMap, "uf_jcl_zpjdsz_dt1");
        }

    }

    /**
     * 同步卡片展示tab页面
     *
     * @param stepId
     * @param flowStepId
     */
    private void syncTab(String stepId, String flowStepId) {
        List<RecruitStepDt2> stepDt2List = getStepDt2List(stepId);

        // 删除原有的数据
        String deleteSql = "delete from uf_jcl_zpjdsz_dt2 where mainid = " + flowStepId;
        RecruitRecordSet.deleteData(deleteSql);
        int order = 0;
        for (RecruitStepDt2 stepDt2 : stepDt2List) {
            order += 10;
            RecruitDataMap<Object> dataMap = new RecruitDataMap<>();
            dataMap.put("mainid", flowStepId);
            dataMap.put("ymbt", stepDt2.getYmbt());
            dataMap.put("ymdz", stepDt2.getYmdz());
            dataMap.put("zssx", Integer.toString(order));
            RecruitRecordSet.insertData(dataMap, "uf_jcl_zpjdsz_dt2");
        }
    }


    /**
     * 获取流程对应的当前阶段ID
     *
     * @param stepId
     * @param recruitFlowId
     * @return
     */
    private String getFlowStepId(String stepId, String recruitFlowId) {
        RecordSet rs = new RecordSet();
        rs.executeQuery("select id from uf_jcl_zpjdsz where zplc = ? and zpjd = ?", recruitFlowId, stepId);
        if (rs.next()) {
            return rs.getString("id");
        }
        return "";
    }


    /**
     * 根据阶段ID，获取该阶段所有的按钮配置集合
     *
     * @param stepId
     * @return
     */
    private List<RecruitStepDt1> getStepDt1List(String stepId) {
        List<RecruitStepDt1> list = new ArrayList<>();
        RecordSet rs = new RecordSet();
        rs.executeQuery("select * from uf_jcl_zpjdsz_dt1 where mainid = ? order by zssx", stepId);
        while (rs.next()) {
            RecruitStepDt1 stepDt1 = RecruitStepDt1.builder()
                    .id(rs.getString("id"))
                    .mainid(rs.getString("mainid"))
                    .czan(rs.getString("czan"))
                    .zdyxsmc(rs.getString("zdyxsmc"))
                    .tzymdz(rs.getString("tzymdz"))
                    .sfqy(rs.getString("sfqy"))
                    .tzymbt(rs.getString("tzymbt"))
                    .zssx(rs.getString("zssx"))
                    .build();
            list.add(stepDt1);
        }
        return list;
    }


    /**
     * 根据阶段ID，获取该阶段所有的tab页面配置集合
     *
     * @param stepId
     * @return
     */
    private List<RecruitStepDt2> getStepDt2List(String stepId) {
        List<RecruitStepDt2> list = new ArrayList<>();
        RecordSet rs = new RecordSet();
        rs.executeQuery("select * from uf_jcl_zpjdsz_dt2 where mainid = ? order by zssx", stepId);
        while (rs.next()) {
            RecruitStepDt2 stepDt1 = RecruitStepDt2.builder()
                    .id(rs.getString("id"))
                    .mainid(rs.getString("mainid"))
                    .ymbt(rs.getString("ymbt"))
                    .ymdz(rs.getString("ymdz"))
                    .zssx(rs.getString("zssx"))
                    .build();
            list.add(stepDt1);
        }
        return list;
    }

}
