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

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
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.core.utils.StringUtils;
import com.scpyun.base.db.service.CommonService;
import com.scpyun.platform.jilinsscgsdp.utils.DataScopeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Api("双属地管理")
@Service("keyPersonRatingDual")
public class KeyPersonRatingDualServiceImpl {
    @Autowired
    private CommonService commonService;

    private static final String SUCCESS = "success";
    private static final String NAMESPACE = "com.scpyun.platform.standard.jilinsscgsdp.keyPersonRatingDual.";

    @ApiOperation(value = "推送tab列表", desc = "查询我辖区内发起的推送记录")
    public Page<Map<String, Object>> selectPushList(Page<Map<String, Object>> page) {
        page.setParams(DataScopeUtil.resetUser(page.getParams()));
        Map<String, Object> params = normalizePageParams(page);
        OperatorContext operator = resolveOperator(params.get("_user"));
        ensureArea(operator);
        params.put("operator_area_id", operator.getAreaId());
        params.put("push_type", "0");
        params.put("sys_type", resolveCategory(params));
        page.setParams(params);
        return commonService.findPage(NAMESPACE + "selectPushList", page);
    }

    @ApiOperation(value = "虎丘当前登录人信息", desc = "查询当前登录人信息")
    public Map<String, Object> selectCurrentUserInfo(Map<String, Object> map) {
        return DataScopeUtil.resetUser(map);
    }


    @ApiOperation(value = "转发tab列表", desc = "查询我辖区内发起的转发记录")
    public Page<Map<String, Object>> selectForwardList(Page<Map<String, Object>> page) {
        page.setParams(DataScopeUtil.resetUser(page.getParams()));
        Map<String, Object> params = normalizePageParams(page);
        OperatorContext operator = resolveOperator(params.get("_user"));
        ensureArea(operator);
        params.put("operator_area_id", operator.getAreaId());
        params.put("push_type", "1");
        params.put("sys_type", resolveCategory(params));
        page.setParams(params);
        return commonService.findPage(NAMESPACE + "selectForwardList", page);
    }

    @ApiOperation(value = "待接收列表", desc = "查询推送/转发给我辖区的记录")
    public Page<Map<String, Object>> selectPendingList(Page<Map<String, Object>> page) {
        page.setParams(DataScopeUtil.resetUser(page.getParams()));
        Map<String, Object> params = normalizePageParams(page);
        OperatorContext operator = resolveOperator(params.get("_user"));
        ensureArea(operator);
        params.put("operator_area_id", operator.getAreaId());
        params.put("sys_type", resolveCategory(params));
        page.setParams(params);
        return commonService.findPage(NAMESPACE + "selectPendingList", page);
    }

    @ApiOperation(value = "接收中人员列表", desc = "查询当前归属于我辖区的人员（D2）")
    public Page<Map<String, Object>> selectReceivingList(Page<Map<String, Object>> page) {
        page.setParams(DataScopeUtil.resetUser(page.getParams()));
        Map<String, Object> params = normalizePageParams(page);
        OperatorContext operator = resolveOperator(params.get("_user"));
        ensureArea(operator);
        params.put("operator_area_id", operator.getAreaId());
        params.put("sys_type", resolveCategory(params));
        page.setParams(params);
        return commonService.findPage(NAMESPACE + "selectReceivingList", page);
    }

    @ApiOperation(value = "被接收人员列表", desc = "查询我辖区发出的并被其他区域接收的人员")
    public Page<Map<String, Object>> selectBeReceivedList(Page<Map<String, Object>> page) {
        page.setParams(DataScopeUtil.resetUser(page.getParams()));
        Map<String, Object> params = normalizePageParams(page);
        OperatorContext operator = resolveOperator(params.get("_user"));
        ensureArea(operator);
        params.put("operator_area_id", operator.getAreaId());
        params.put("sys_type", resolveCategory(params));
        page.setParams(params);
        return commonService.findPage(NAMESPACE + "selectBeReceivedList", page);
    }

    @ApiOperation(value = "推送人员选择列表", desc = "查询本辖区可推送的重点人员")
    public Page<Map<String, Object>> selectBelongPersonList(Page<Map<String, Object>> page) {
        page.setParams(DataScopeUtil.resetUser(page.getParams()));
        Map<String, Object> params = normalizePageParams(page);
        OperatorContext operator = resolveOperator(params.get("_user"));
        ensureArea(operator);
        params.put("operator_area_id", operator.getAreaId());
        params.put("sys_type", resolveCategory(params));
        page.setParams(params);
        return commonService.findPage(NAMESPACE + "selectBelongPersonList", page);
    }

    @ApiOperation(value = "推送/转发详情", desc = "根据记录ID获取完整信息")
    public Map<String, Object> getDualDetail(Map<String, Object> map) {
        map = DataScopeUtil.resetUser(map);
        Map<String, Object> params = normalizeParams(map);
        if (StringUtils.isEmpty(StringUtils.toString(params.get("id")))) {
            throw new CustomException("记录ID不可为空");
        }
        Map<String, Object> detail = commonService.getObject(NAMESPACE + "getDualDetail", params);
        if (detail == null) {
            throw new CustomException("未查询到记录");
        }
        return detail;
    }

    @ApiOperation(value = "发起推送/转发", desc = "推送tab及转发操作共用")
    public String savePush(Map<String, Object> map) {
        map = DataScopeUtil.resetUser(map);
        Map<String, Object> params = normalizeParams(map);
        OperatorContext operator = resolveOperator(params.get("_user"));
        ensureArea(operator);
        String keyPersonId = StringUtils.toString(params.get("key_person_id"));
        String sysType = resolveCategory(params);
        String pushType = StringUtils.isEmpty(StringUtils.toString(params.get("push_type"))) ? "0" : StringUtils.toString(params.get("push_type"));
        String targetAreaId = StringUtils.toString(params.get("recvie_area_id"));
        String targetStreetId = StringUtils.toString(params.get("recvie_street_id"));
        if (StringUtils.isEmpty(keyPersonId)) {
            throw new CustomException("请选择重点人员");
        }
        if (StringUtils.isEmpty(targetAreaId)) {
            throw new CustomException("请选择推送区县");
        }
        if (StringUtils.isEmpty(targetStreetId)) {
            throw new CustomException("请选择推送街道");
        }
        if (operator.getAreaId().equals(targetAreaId)) {
            throw new CustomException("不可推送至本区域");
        }
        params.put("key_person_id", keyPersonId);
        params.put("sys_type", sysType);
        Map<String, Object> record = new HashMap<>();
        Map<String, Object> personBase = commonService.getObject(NAMESPACE + "getPersonBase", params);
        if (personBase == null) {
            throw new CustomException("未查询到重点人员");
        }
        Map<String, Object> dualCtx = commonService.getObject(NAMESPACE + "getDualContextByKeyPersonId", params);
        Object pendingObj = commonService.getObject(NAMESPACE + "countPendingPush", params);
        String pendingStr = StringUtils.toString(pendingObj);
        int pendingCount = StringUtils.isEmpty(pendingStr) ? 0 : Integer.parseInt(pendingStr);
        if (pendingCount > 0) {
            throw new CustomException("当前人员已有待接收记录，请勿重复发起");
        }
        Date now = new Date();
        record.put("id", UUID.randomUUID().toString().replace("-", ""));
        record.put("key_person_id", keyPersonId);
        record.put("sys_type", sysType);
        record.put("push_type", pushType);
        record.put("push_status", "1");
        record.put("push_reason", params.get("push_reason"));
        record.put("push_time", now);
        record.put("push_user", operator.getUserId());
        record.put("push_duty_phone", params.get("push_duty_phone"));//推送负责人电话
        record.put("create_user", operator.getUserId());
        record.put("create_time", now);
        record.put("update_user", operator.getUserId());
        record.put("update_time", now);
        record.put("recvie_region", StringUtils.toString(params.get("recvie_region")));
        record.put("recvie_city_id", params.get("recvie_city_id"));
        record.put("recvie_area_id", targetAreaId);
        record.put("recvie_street_id", targetStreetId);
        record.put("recvie_community_id", params.get("recvie_community_id"));
        if ("0".equals(pushType)) {
            // 首次推送，取人员所属区域作为归属&推送方
            if (dualCtx != null) {
                throw new CustomException("该人员已在外部归属，无法再次推送");
            }
            String belongRegion = StringUtils.toString(personBase.get("region"));
            record.put("belong_region", belongRegion);
            record.put("belong_city_id", personBase.get("city_id"));
            record.put("belong_area_id", personBase.get("area_id"));
            record.put("belong_street_id", personBase.get("street_id"));
            record.put("belong_community_id", personBase.get("community_id"));
            record.put("belong_user_id", operator.getUserId());
            record.put("push_region", belongRegion);
            record.put("push_city_id", personBase.get("city_id"));
            record.put("push_area_id", personBase.get("area_id"));
            record.put("push_street_id", personBase.get("street_id"));
            record.put("push_community_id", personBase.get("community_id"));
        } else {
            if (dualCtx == null) {
                throw new CustomException("当前人员不在双属地列表，无法转发");
            }
            if (!operator.getAreaId().equals(StringUtils.toString(dualCtx.get("area_id")))) {
                throw new CustomException("仅当前接收区域可转发");
            }
            if (targetAreaId.equals(StringUtils.toString(dualCtx.get("belong_area_id")))) {
                throw new CustomException("转发不可回归归属地，请使用退回操作");
            }
            String belongRegion = StringUtils.toString(dualCtx.get("belong_region"));
            record.put("belong_region", belongRegion);
            record.put("belong_city_id", dualCtx.get("belong_city_id"));
            record.put("belong_area_id", dualCtx.get("belong_area_id"));
            record.put("belong_street_id", dualCtx.get("belong_street_id"));
            record.put("belong_community_id", dualCtx.get("belong_community_id"));
            String belongUser = StringUtils.toString(dualCtx.get("belong_user_id"));
            record.put("belong_user_id", StringUtils.isEmpty(belongUser) ? operator.getUserId() : belongUser);
            record.put("push_region", dualCtx.get("region"));
            record.put("push_city_id", dualCtx.get("city_id"));
            record.put("push_area_id", dualCtx.get("area_id"));
            record.put("push_street_id", dualCtx.get("street_id"));
            record.put("push_community_id", dualCtx.get("community_id"));
        }
        if (commonService.insert(NAMESPACE + "insertDualRecord", record) != 1) {
            throw new CustomException("保存推送失败");
        }
        if ("1".equals(pushType) && dualCtx != null) {
            Map<String, Object> turnParams = new HashMap<>();
            turnParams.put("id", dualCtx.get("id"));
            turnParams.put("turn_status", "1");
            turnParams.put("update_user", operator.getUserId());
            turnParams.put("update_time", now);
            commonService.update(NAMESPACE + "updateDualPersonTurnStatus", turnParams);
        }
        return SUCCESS;
    }

    @ApiOperation(value = "撤回推送/转发", desc = "仅待接收状态可撤回")
    public String revokePush(Map<String, Object> map) {
        map = DataScopeUtil.resetUser(map);
        Map<String, Object> params = normalizeParams(map);
        OperatorContext operator = resolveOperator(params.get("_user"));
        ensureArea(operator);
        String id = StringUtils.toString(params.get("id"));
        if (StringUtils.isEmpty(id)) {
            throw new CustomException("记录ID不可为空");
        }
        Map<String, Object> record = commonService.getObject(NAMESPACE + "getDualRecordById", params);
        if (record == null) {
            throw new CustomException("未查询到记录");
        }
        if (!"1".equals(StringUtils.toString(record.get("push_status")))) {
            throw new CustomException("仅待接收状态可撤回");
        }
        if (!operator.getAreaId().equals(StringUtils.toString(record.get("push_area_id")))) {
            throw new CustomException("无权撤回他区记录");
        }
        Map<String, Object> update = new HashMap<>();
        update.put("id", id);
        update.put("update_user", operator.getUserId());
        update.put("update_time", new Date());
        if (commonService.update(NAMESPACE + "revokeDualRecord", update) != 1) {
            throw new CustomException("撤回失败");
        }
        if ("1".equals(StringUtils.toString(record.get("push_type")))) {
            Map<String, Object> turnParams = new HashMap<>();
            turnParams.put("key_person_id", record.get("key_person_id"));
            turnParams.put("turn_status", "0");
            turnParams.put("update_user", operator.getUserId());
            turnParams.put("update_time", new Date());
            commonService.update(NAMESPACE + "resetDualPersonTurnStatus", turnParams);
        }
        return SUCCESS;
    }

    @ApiOperation(value = "同意接收", desc = "待接收tab操作")
    public String acceptPush(Map<String, Object> map) {
        map = DataScopeUtil.resetUser(map);
        Map<String, Object> params = normalizeParams(map);
        OperatorContext operator = resolveOperator(params.get("_user"));
        ensureArea(operator);
        String id = StringUtils.toString(params.get("id"));
        if (StringUtils.isEmpty(id)) {
            throw new CustomException("记录ID不可为空");
        }
        String communityId = StringUtils.toString(params.get("recvie_community_id"));
        if (StringUtils.isEmpty(communityId)) {
            throw new CustomException("请选择社区信息");
        }
        Map<String, Object> record = commonService.getObject(NAMESPACE + "getDualRecordById", params);
        if (record == null) {
            throw new CustomException("未查询到记录");
        }
        if (!"1".equals(StringUtils.toString(record.get("push_status")))) {
            throw new CustomException("当前状态不可接收");
        }
        if (!operator.getAreaId().equals(StringUtils.toString(record.get("recvie_area_id")))) {
            throw new CustomException("仅目标区域可接收");
        }
        Date now = new Date();
        Map<String, Object> update = new HashMap<>();
        update.put("id", id);
        update.put("recvie_community_id", communityId);
        update.put("audit_user", operator.getUserId());
        update.put("audit_time", now);
        update.put("recvie_time", now);
        update.put("update_user", operator.getUserId());
        update.put("update_time", now);
        if (commonService.update(NAMESPACE + "acceptDualRecord", update) != 1) {
            throw new CustomException("接收失败");
        }
        Map<String, Object> ctx = new HashMap<>();
        ctx.put("key_person_id", record.get("key_person_id"));
        Map<String, Object> dualCtx = commonService.getObject(NAMESPACE + "getDualContextByKeyPersonId", ctx);
        Map<String, Object> personUpsert = new HashMap<>();
        if (dualCtx == null) {
            personUpsert.put("id", UUID.randomUUID().toString().replace("-", ""));
            personUpsert.put("create_user", operator.getUserId());
            personUpsert.put("create_time", now);
            personUpsert.put("key_person_id", record.get("key_person_id"));
            personUpsert.put("sys_type", record.get("sys_type"));
        } else {
            personUpsert.put("id", dualCtx.get("id"));
            personUpsert.put("update_user", operator.getUserId());
            personUpsert.put("update_time", now);
        }
        personUpsert.put("dual_id", id);
        personUpsert.put("region", record.get("recvie_region"));
        personUpsert.put("city_id", record.get("recvie_city_id"));
        personUpsert.put("area_id", record.get("recvie_area_id"));
        personUpsert.put("street_id", record.get("recvie_street_id"));
        personUpsert.put("community_id", communityId);
        personUpsert.put("turn_status", "0");
        if (dualCtx == null) {
            if (commonService.insert(NAMESPACE + "insertDualPerson", personUpsert) != 1) {
                throw new CustomException("写入归属表失败");
            }
        } else {
            if (commonService.update(NAMESPACE + "updateDualPerson", personUpsert) != 1) {
                throw new CustomException("更新归属表失败");
            }
        }
        return SUCCESS;
    }

    @ApiOperation(value = "拒绝接收", desc = "待接收tab操作")
    public String rejectPush(Map<String, Object> map) {
        map = DataScopeUtil.resetUser(map);
        Map<String, Object> params = normalizeParams(map);
        OperatorContext operator = resolveOperator(params.get("_user"));
        ensureArea(operator);
        String id = StringUtils.toString(params.get("id"));
        if (StringUtils.isEmpty(id)) {
            throw new CustomException("记录ID不可为空");
        }
        String reason = StringUtils.toString(params.get("reject_reason"));
        if (StringUtils.isEmpty(reason)) {
            throw new CustomException("请填写拒绝原因");
        }
        Map<String, Object> record = commonService.getObject(NAMESPACE + "getDualRecordById", params);
        if (record == null) {
            throw new CustomException("未查询到记录");
        }
        if (!"1".equals(StringUtils.toString(record.get("push_status")))) {
            throw new CustomException("当前状态不可拒绝");
        }
        if (!operator.getAreaId().equals(StringUtils.toString(record.get("recvie_area_id")))) {
            throw new CustomException("仅目标区域可拒绝");
        }
        Date now = new Date();
        Map<String, Object> update = new HashMap<>();
        update.put("id", id);
        update.put("reject_reason", reason);
        update.put("audit_user", operator.getUserId());
        update.put("audit_time", now);
        update.put("update_user", operator.getUserId());
        update.put("update_time", now);
        if (commonService.update(NAMESPACE + "rejectDualRecord", update) != 1) {
            throw new CustomException("拒绝失败");
        }
        if ("1".equals(StringUtils.toString(record.get("push_type")))) {
            Map<String, Object> turnParams = new HashMap<>();
            turnParams.put("key_person_id", record.get("key_person_id"));
            turnParams.put("turn_status", "0");
            turnParams.put("update_user", operator.getUserId());
            turnParams.put("update_time", now);
            commonService.update(NAMESPACE + "resetDualPersonTurnStatus", turnParams);
        }
        return SUCCESS;
    }

    @ApiOperation(value = "退回人员", desc = "接收中tab退回归属地")
    public String returnPerson(Map<String, Object> map) {
        map = DataScopeUtil.resetUser(map);
        Map<String, Object> params = normalizeParams(map);
        OperatorContext operator = resolveOperator(params.get("_user"));
        ensureArea(operator);
        String dualPersonId = StringUtils.toString(params.get("dual_person_id"));
        if (StringUtils.isEmpty(dualPersonId)) {
            throw new CustomException("缺少归属记录ID");
        }
        Map<String, Object> dualPerson = commonService.getObject(NAMESPACE + "getDualPersonById", params);
        if (dualPerson == null) {
            throw new CustomException("未找到归属记录");
        }
        if (!operator.getAreaId().equals(StringUtils.toString(dualPerson.get("area_id")))) {
            throw new CustomException("仅当前接收区域可退回");
        }
        String dualId = StringUtils.toString(dualPerson.get("dual_id"));
        if (StringUtils.isEmpty(dualId)) {
            throw new CustomException("归属数据异常，缺少推送记录");
        }
        Date now = new Date();
        Map<String, Object> update = new HashMap<>();
        update.put("id", dualId);
        update.put("return_reason", params.get("return_reason"));
        update.put("return_user", operator.getUserId());
        update.put("return_time", now);
        update.put("update_user", operator.getUserId());
        update.put("update_time", now);
        if (commonService.update(NAMESPACE + "returnDualRecord", update) != 1) {
            throw new CustomException("退回失败");
        }
        if (commonService.delete(NAMESPACE + "deleteDualPerson", dualPerson) != 1) {
            throw new CustomException("删除归属记录失败");
        }
        return SUCCESS;
    }

    private Map<String, Object> normalizePageParams(Page<Map<String, Object>> page) {
        Map<String, Object> params = page.getParams() == null ? new HashMap<>() : new HashMap<>(page.getParams());
        Object inner = params.get("params");
        if (inner instanceof Map) {
            @SuppressWarnings("unchecked")
            Map<String, Object> innerParams = (Map<String, Object>) inner;
            Map<String, Object> merged = new HashMap<>(params);
            merged.remove("params");
            merged.putAll(innerParams);
            params = merged;
        }
        page.setParams(params);
        return params;
    }

    private Map<String, Object> normalizeParams(Map<String, Object> map) {
        return map == null ? new HashMap<>() : new HashMap<>(map);
    }

    private OperatorContext resolveOperator(Object userObj) {
        if (userObj == null) {
            throw new CustomException("未获取到登录信息");
        }
        JSONObject json = JSONObject.parseObject(JSONObject.toJSONString(userObj));
        Map<String, String> pos = DataScopeUtil.getPosition(userObj);
        OperatorContext ctx = new OperatorContext();
        ctx.setUserId(json.getString("id"));
        if (pos != null) {
            ctx.setAreaId(pos.get("area_id"));
        }
        return ctx;
    }

    private void ensureArea(OperatorContext operator) {
        if (operator == null || StringUtils.isEmpty(operator.getAreaId())) {
            throw new CustomException("未定位到所属区县，无法执行操作");
        }
    }

    private String resolveCategory(Map<String, Object> params) {
        Object sysType = params.get("sys_type");
        if (sysType == null) {
            sysType = params.get("rating_dict_type");
        }
        if (sysType == null) {
            sysType = params.get("category");
        }
        if (sysType == null) {
            throw new CustomException("缺少重点人员类别");
        }
        String value = StringUtils.toString(sysType);
        params.put("sys_type", value);
        return value;
    }


    private static class OperatorContext {
        private String userId;
        private String areaId;

        public String getUserId() {
            return userId;
        }

        public void setUserId(String userId) {
            this.userId = userId;
        }

        public String getAreaId() {
            return areaId;
        }

        public void setAreaId(String areaId) {
            this.areaId = areaId;
        }
    }

    @ApiOperation(value = "预警tab列表", desc = "查询推送超过24小时未处理的数据")
    public Page<Map<String, Object>> selectDualWarnPushList(Page<Map<String, Object>> page) {
        page.setParams(DataScopeUtil.resetUser(page.getParams()));
        Map<String, Object> params = normalizePageParams(page);
//        OperatorContext operator = resolveOperator(params.get("_user"));
//        params.put("operator_area_id", operator.getUserId());
        page.setParams(params);
        return commonService.findPage(NAMESPACE + "selectDualWarnPushList", page);
    }

    @ApiOperation(value = "电话tab列表", desc = "查询长春市通讯录")
    public Page<Map<String, Object>> selectDualPhoneList(Page<Map<String, Object>> page) {
        page.setParams(DataScopeUtil.resetUser(page.getParams()));
        Map<String, Object> params = normalizePageParams(page);
//        OperatorContext operator = resolveOperator(params.get("_user"));
//        params.put("operator_area_id", operator.getUserId());
        page.setParams(params);
        return commonService.findPage(NAMESPACE + "selectDualPhoneList", page);
    }

    @ApiOperation(value = "保存通讯录", desc = "保存对应机构的通讯录电话")
    public String saveDualPhone(Map<String, Object> map) {
        map = DataScopeUtil.resetUser(map);
        Map<String, Object> params = normalizeParams(map);
        OperatorContext operator = resolveOperator(params.get("_user"));
        map.put("userId", operator.getUserId());
        String newId = null;
        if(map.get("mark_id") != null) {
            newId = String.valueOf(map.get("mark_id"));
            if (commonService.update(NAMESPACE + "updateDualPhone", map) != 1) {
                throw new CustomException("更新通讯录失败");
            }
        }else{
            newId = IdUtil.simpleUUID();
            map.put("mark_id", newId);
            if (commonService.insert(NAMESPACE + "insertDualPhone", map) != 1) {
                throw new CustomException("保存通讯录失败");
            }
        }
        return newId;
    }
}
