package org.hzhub.workflow.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hzhub.common.core.constant.SystemConstants;
import org.hzhub.common.satoken.utils.LoginHelper;
import org.hzhub.common.tenant.helper.TenantHelper;
import org.hzhub.system.domain.SysDept;
import org.hzhub.system.domain.bo.SysDeptBo;
import org.hzhub.system.domain.vo.SysDeptVo;
import org.hzhub.system.mapper.SysDeptMapper;
import org.hzhub.system.service.ISysDeptService;
import org.hzhub.workflow.service.IWecomDeptSyncService;
import org.hzhub.workflow.service.IWecomTenantConfigService;
import org.hzhub.workflow.wecom.WecomApiClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 企业微信部门同步服务实现
 * <p>通过 ISysDeptService 创建/更新部门，确保 tenant_id、del_flag 等字段正确设置</p>
 *
 * @author hzhub
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WecomDeptSyncServiceImpl implements IWecomDeptSyncService {

    private final WecomApiClient wecomApiClient;
    private final ISysDeptService deptService;
    private final SysDeptMapper deptMapper;
    private final IWecomTenantConfigService tenantConfigService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String syncFromWecom() {
        if (!isConfigured()) {
            return "企业微信未配置，无法同步";
        }

        log.info("开始同步企业微信部门数据");

        String resp = wecomApiClient.listDepartments(null);
        var json = JSONUtil.parseObj(resp);
        int errcode = json.getInt("errcode", -1);
        if (errcode != 0) {
            String errmsg = json.getStr("errmsg");
            log.error("获取企业微信部门列表失败: {}", errmsg);
            return "同步失败: " + errmsg;
        }

        JSONArray deptArray = json.getJSONArray("department");
        if (deptArray == null || deptArray.isEmpty()) {
            return "企业微信无部门数据";
        }

        // 忽略租户过滤查询所有部门，用于匹配 WeCom 部门ID
        List<SysDeptVo> allDepts = TenantHelper.ignore(() -> deptService.selectDeptList(new SysDeptBo()));
        Map<Integer, SysDeptVo> existingByWecomId = new HashMap<>();
        Map<Integer, Long> wecomIdToSysDeptId = new HashMap<>();
        for (SysDeptVo d : allDepts) {
            if (d.getDeptCategory() != null) {
                try {
                    int wecomId = Integer.parseInt(d.getDeptCategory());
                    existingByWecomId.put(wecomId, d);
                    wecomIdToSysDeptId.put(wecomId, d.getDeptId());
                } catch (NumberFormatException ignored) {
                }
            }
        }

        int created = 0;
        int updated = 0;

        // 按 parentid 排序，保证父部门先处理
        List<JSONObject> sortedDepts = deptArray.stream()
            .map(j -> (JSONObject) j)
            .sorted(Comparator.comparing(j -> j.getInt("parentid")))
            .toList();

        for (JSONObject deptJson : sortedDepts) {
            int wecomId = deptJson.getInt("id");
            int parentid = deptJson.getInt("parentid", 0);
            String name = deptJson.getStr("name");
            int order = deptJson.getInt("order", 0);
            // 企业微信 order 越大越靠前，sys_dept orderNum 升序，取负值转换
            int orderNum = -order;

            try {
                SysDeptVo existing = existingByWecomId.get(wecomId);

                Long parentDeptId;
                if (parentid == 0) {
                    parentDeptId = 0L;
                } else {
                    parentDeptId = wecomIdToSysDeptId.get(parentid);
                    if (parentDeptId == null) {
                        log.warn("部门 [{}] 的父部门 {} 不存在，跳过", name, parentid);
                        continue;
                    }
                }

                if (existing != null) {
                    // 更新现有部门
                    SysDeptBo bo = new SysDeptBo();
                    bo.setDeptId(existing.getDeptId());
                    bo.setDeptName(name);
                    bo.setParentId(parentDeptId);
                    bo.setOrderNum(orderNum);
                    bo.setStatus(SystemConstants.NORMAL);
                    bo.setDeptCategory(String.valueOf(wecomId));
                    deptService.updateDept(bo);
                    updated++;
                } else {
                    // 新增部门
                    SysDeptBo bo = new SysDeptBo();
                    bo.setDeptName(name);
                    bo.setParentId(parentDeptId);
                    bo.setOrderNum(orderNum);
                    bo.setStatus(SystemConstants.NORMAL);
                    bo.setDeptCategory(String.valueOf(wecomId));

                    if (parentDeptId == 0L) {
                        // 根部门：insertDept 需要查父部门(0不存在)，直接通过 mapper 插入
                        insertRootDept(bo);
                    } else {
                        deptService.insertDept(bo);
                    }
                    wecomIdToSysDeptId.put(wecomId, bo.getDeptId());
                    created++;
                }
            } catch (Exception e) {
                log.error("同步部门 [{}] 失败", name, e);
            }
        }

        String msg = String.format("同步完成，新增 %d 个，更新 %d 个", created, updated);
        log.info(msg);

        // 修复：补全之前同步但缺少 tenant_id 的部门
        int fixedTenant = fixMissingTenantId();
        if (fixedTenant > 0) {
            msg += String.format("，修复 %d 个缺失租户ID的部门", fixedTenant);
        }

        return msg;
    }

    /**
     * 修复缺少 tenant_id 的 WeCom 同步部门
     */
    private int fixMissingTenantId() {
        String tenantId = LoginHelper.getTenantId();
        if (tenantId == null) {
            return 0;
        }

        int count = 0;
        // 忽略租户过滤查找所有部门
        List<SysDept> allDepts = TenantHelper.ignore(() -> deptMapper.selectList(
            new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<SysDept>()
                .isNotNull(SysDept::getDeptCategory)
        ));

        for (SysDept dept : allDepts) {
            if (ObjectUtil.isNull(dept.getTenantId())) {
                dept.setTenantId(tenantId);
                deptMapper.updateById(dept);
                count++;
            }
        }

        if (count > 0) {
            log.info("修复 {} 个缺少 tenant_id 的 WeCom 同步部门", count);
        }
        return count;
    }

    /**
     * 插入根部门（parentId = 0）
     * <p>insertDept 需要查父部门来构建 ancestors，但根部门没有父部门，所以直接通过 mapper 插入</p>
     */
    private void insertRootDept(SysDeptBo bo) {
        String tenantId = LoginHelper.getTenantId();

        SysDept dept = new SysDept();
        dept.setDeptName(bo.getDeptName());
        dept.setParentId(0L);
        dept.setAncestors("0");
        dept.setOrderNum(bo.getOrderNum());
        dept.setStatus(bo.getStatus());
        dept.setDeptCategory(bo.getDeptCategory());
        dept.setDelFlag(SystemConstants.NORMAL);
        if (tenantId != null) {
            dept.setTenantId(tenantId);
        }

        deptMapper.insert(dept);
        bo.setDeptId(dept.getDeptId());
    }

    private boolean isConfigured() {
        return tenantConfigService.getByCurrentTenant() != null;
    }
}
