package com.scpyun.platform.jilinsscgsdp.service.impl;

import com.scpyun.platform.jilinsscgsdp.utils.DataScopeUtil;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import com.scpyun.base.bean.Page;
import com.scpyun.base.core.annotation.Api;
import com.scpyun.base.core.annotation.ApiOperation;
import com.scpyun.base.core.exception.CustomException;
import com.scpyun.base.db.service.CommonService;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.xml.crypto.Data;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static java.time.LocalTime.now;

@Api("日常请假管理")
@Service("keyDmLeave")
public class KeyDmLeaveServiceImpl {
    @Autowired
    private CommonService commonService;

    private static final String SUCCESS = "success";
    private final String namespace = "com.scpyun.platform.standard.jilinsscgsdp.keyDmLeave.";
    private final String leaveTypeNamespace = "com.scpyun.platform.standard.jilinsscgsdp.keyDmUserCategory.";
    private final String approvalRecordNamespace = "com.scpyun.platform.standard.jilinsscgsdp.keyDmLeaveApprovalRecord.";

    @ApiOperation(value = "请假申请查询", desc = "分页查询")
    public Page<Map<String, Object>> selectList(Page<Map<String, Object>> map) {
        if (map == null) map = new Page<>();
        Map<String, Object> user = (Map<String, Object>) map.getParams().get("_user");
        Map<String, String> pos = DataScopeUtil.getPosition(user);
        map.getParams().put("area_id", pos.get("area_id"));
        Page<Map<String, Object>> map1 = commonService.findPage(namespace + "selectList", map);
        return map1;
    }
    @ApiOperation(value = "请假申请", desc = "分页查询")
    public Page<Map<String, Object>> selectListByUserId(Page<Map<String, Object>> map) {
        if (map == null) map = new Page<>();
        Page<Map<String, Object>> map1 = commonService.findPage(namespace + "selectListByUserId", map);
        return map1;
    }
    @ApiOperation(value = "请假待审核", desc = "分页查询")
    public Page<Map<String, Object>> selectPendingList(Map<String, Object> map) {
        if (map == null) map = new HashMap<>();
        return commonService.findPage(namespace + "selectPendingList", map);
    }

    @ApiOperation(value = "待审核列表", desc = "查询待审核数据")
    public List<Map<String, Object>> selectTransferApprovalList(Map<String, Object> map) {
        if (map == null) map = new HashMap<>();
        return commonService.findList(namespace + "selectTransferApprovalList", map);
    }
    @ApiOperation(value = "待审核列表", desc = "查询待审核数据")
    public String deleteById(Map<String, Object> map) {
        if (map == null) map = new HashMap<>();
        int aff = commonService.update(namespace + "deleteById", map);
        commonService.findList(approvalRecordNamespace + "deleteById", map);

        if (aff < 0) throw new CustomException("审批失败");
        return SUCCESS;
    }
    @ApiOperation(value = "保存请假申请", desc = "新增或修改，请假单保存")
    public String save(Map<String, Object> map) {
        if (map == null) throw new CustomException("参数不能为空");

        Object id = map.get("id");
        Object leave_id = map.get("leave_id");

        if (leave_id == null || String.valueOf(leave_id).trim().isEmpty()) {
            // 新增：生成主表id，id为子表id（如果前端没传则生成新的）
            String mainId = UUID.randomUUID().toString();
            // 主表主键在 mapper 中使用名称 leave_id，确保插入时传入正确的字段名
            map.put("leave_id", mainId);
            // 为兼容可能使用 'id' 作为主表参数的旧调用方，同时设置 'id'
            // 这样能避免在 mapper 绑定时出现 id 为空导致的约束错误
            map.put("id", mainId);
            String typeId = map.get("leave_type_id").toString();
            String typeName = commonService.getObject(leaveTypeNamespace + "selectLeaveTypeById", typeId);
            map.put("leave_type_name", typeName);
            map.put("status", 0); // 默认保存状态为0

            if (commonService.insert(namespace + "insert", map) != 1) {
                throw new CustomException("保存失败");
            }
            // 如果请求中包含审批人信息，插入初始的审批记录到子表（jl_key_dm_leave_approval_record）
            try {
                Object approverId = map.get("approver_id");
                Object approverName = map.get("approver_name");
                if ((approverId != null && String.valueOf(approverId).trim().length() > 0) ||
                        (approverName != null && String.valueOf(approverName).trim().length() > 0)) {
                    Map<String, Object> approvalRecord = new HashMap<>();
                    approvalRecord.put("id", id == null || String.valueOf(id).trim().isEmpty() ? UUID.randomUUID().toString() : String.valueOf(id)); // 子表id
                    approvalRecord.put("leave_id", mainId); // 主表id
                    approvalRecord.put("node_index", 1);
                    approvalRecord.put("node_type", 1); // 1 = 流程节点
                    approvalRecord.put("approver_id", approverId == null ? null : String.valueOf(approverId));
                    approvalRecord.put("approver_name", approverName == null ? null : String.valueOf(approverName));
                    approvalRecord.put("approver_result", 0); // 0 未处理
                    approvalRecord.put("approver_time", null);
                    approvalRecord.put("status", 0); // 0 未操作
                    approvalRecord.put("comment", null);
                    approvalRecord.put("order_no", 1);
                    // 插入子表，mapper id 为 insert
                    commonService.insert(approvalRecordNamespace + "insert", approvalRecord);
                }
            } catch (Exception e) {
                // 子表插入异常不影响主表保存，但记录日志以便排查
                throw new CustomException("保存审批子表记录失败：" + e.getMessage());
            }
        } else {
            // 编辑：id为子表id，leave_id为主表id，更新主表时用leave_id
            Map<String, Object> updateMap = new HashMap<>(map);
            updateMap.put("id", leave_id); // 更新主表时用主表id
            int aff = commonService.update(namespace + "update", updateMap);
            if (aff < 0) {
                throw new CustomException("保存失败");
            }
            // 如果有子表记录需要更新（审批记录）
            if (id != null && !String.valueOf(id).trim().isEmpty()) {
                try {
                    Map<String, Object> approvalRecord = new HashMap<>();
                    approvalRecord.put("id", String.valueOf(id)); // 子表id
                    approvalRecord.put("leave_id", leave_id); // 主表id
                    // 复制其他需要更新的字段
                    Object approverId = map.get("approver_id");
                    Object approverName = map.get("approver_name");
                    if (approverId != null) approvalRecord.put("approver_id", String.valueOf(approverId));
                    if (approverName != null) approvalRecord.put("approver_name", String.valueOf(approverName));
                    // 更新子表记录
                    commonService.update(approvalRecordNamespace + "update", approvalRecord);
                } catch (Exception e) {
                    // 子表更新异常不影响主表保存
                    throw new CustomException("保存审批子表记录失败：" + e.getMessage());
                }
            }
        }
        return SUCCESS;
    }

    @ApiOperation(value = "提交请假申请", desc = "提交进入审批流程")
    public String submit(Map<String, Object> map) {
        if (map == null || map.get("leave_id") == null) throw new CustomException("参数缺失");
        int aff = commonService.update(namespace + "submit", map);
        commonService.update(approvalRecordNamespace + "submit", map);
        if (aff < 0) throw new CustomException("提交失败");
        return SUCCESS;
    }

    @ApiOperation(value = "撤回请假申请", desc = "撤回未完成审批的申请")
    public String revoke(Map<String, Object> map) {
        if (map == null || map.get("leave_id") == null) throw new CustomException("参数缺失");
        int aff = commonService.update(namespace + "revoke", map);
        commonService.update(approvalRecordNamespace + "revoke", map);
        if (aff < 0) throw new CustomException("撤回失败");
        return SUCCESS;
    }

    @ApiOperation(value = "审批通过", desc = "审批操作-通过")
    public String approve(Map<String, Object> map) {
        if (map == null || map.get("leave_id") == null) throw new CustomException("参数缺失");
        int aff = commonService.update(namespace + "approve", map);
        commonService.update(approvalRecordNamespace + "approve", map);
        if (aff < 0) throw new CustomException("审批失败");
        return SUCCESS;
    }

    @ApiOperation(value = "审批驳回", desc = "审批操作-驳回")
    public String reject(Map<String, Object> map) {
        if (map == null || map.get("leave_id") == null) throw new CustomException("参数缺失");
        int aff = commonService.update(namespace + "reject", map);

        commonService.update(approvalRecordNamespace + "reject", map);
        if (aff < 0) throw new CustomException("驳回失败");
        return SUCCESS;
    }

    @ApiOperation(value = "转审批", desc = "审批操作-转审批")
    public String transferApproval(Map<String, Object> map) {
        if (map == null || map.get("id") == null) throw new CustomException("参数缺失");
        Map<String, Object> leave  = commonService.getObject(approvalRecordNamespace + "selectById", map);
        int aff = commonService.update(approvalRecordNamespace + "transferApproval", map);
        commonService.update(namespace + "transferApproval", map);
        leave.put("id", UUID.randomUUID().toString());
        leave.put("approver_id", map.get("approver_id"));
        leave.put("approver_name", map.get("approver_name"));
        DateTime now = DateTime.now();
        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
        String approverTimeStr = now.toString(formatter);
        leave.put("approver_time", approverTimeStr);
        leave.put("node_type",2);
        leave.put("node_index", Integer.parseInt(leave.get("node_index").toString()) + 1);
        commonService.insert(approvalRecordNamespace + "insert", leave);
        if (aff < 0) throw new CustomException("转审批失败");
        return SUCCESS;
    }


    @ApiOperation(value = "获取请假详情（含审批记录）", desc = "获取详情")
    public Map<String, Object> getById(Map<String, Object> map) {
        if (map == null || map.get("id") == null) throw new CustomException("参数缺失");
        Map<String, Object> ret = new HashMap<>();
        // 兼容 mapper 中使用的参数名（mapper 使用 #{leave_id}），
        // 将传入的 id 同步为 leave_id，确保 SQL 能正确匹配到主表记录
        if (map.get("leave_id") == null) {
            map.put("leave_id", map.get("id"));
        }
        Map<String, Object> app = commonService.getObject(namespace + "getById", map);
        ret.putAll(app == null ? new HashMap<>() : app);
        // 子表：审批记录
        List<Map<String, Object>> approvals = commonService.findList(approvalRecordNamespace + "selectApprovalRecords", map);
        approvals = approvals == null ? new java.util.ArrayList<>() : approvals;
        ret.put("approvals", approvals);

        // 从审批记录中获取审批人信息（取第一条记录的审批人信息）
        if (!approvals.isEmpty()) {
            Map<String, Object> firstApproval = approvals.get(0);
            if (firstApproval.get("approver_id") != null) {
                ret.put("approver_id", firstApproval.get("approver_id"));
            }
            if (firstApproval.get("approver_name") != null) {
                ret.put("approver_name", firstApproval.get("approver_name"));
            }
        }

        // 将子表统一放入 subTables 集合，便于前端区分不同子表
        Map<String, List<Map<String, Object>>> subTables = new HashMap<>();
        subTables.put("approvalRecords", approvals);
        ret.put("subTables", subTables);
        return ret;
    }

    @ApiOperation(value = "审批历史查询", desc = "查询审批历史")
    public Page<Map<String, Object>> selectApprovalHistory(Page<Map<String, Object>> map) {
        if (map == null) map = new Page<>();
        Map<String, Object> user = (Map<String, Object>) map.getParams().get("_user");
        Map<String, String> pos = DataScopeUtil.getPosition(user);
        map.getParams().put("area_id", pos.get("area_id"));
        return commonService.findPage(approvalRecordNamespace + "selectApprovalHistory", map);
    }

    @ApiOperation(value = "请假统计", desc = "按人员统计已通过请假天数")
    public List<Map<String, Object>> selectStats(Map<String, Object> map) {
        if (map == null) map = new HashMap<>();
        Map<String, Object> user = (Map<String, Object>) map.get("_user");
        Map<String, String> pos = DataScopeUtil.getPosition(user);
        map.put("area_id", pos.get("area_id"));
        return commonService.findList(namespace + "selectStats", map);
    }
}


