package com.fs.company.util;

import com.fs.common.utils.StringUtils;
import com.fs.company.domain.CompanyDept;
import com.fs.company.domain.CompanyMiniapp;
import com.fs.company.domain.CompanyUser;
import com.fs.voice.utils.StringUtil;

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

/**
 * 小程序SOP工具类，根据用户、部门、企业信息解析对应小程序appId，区分主小程序/服务小程序
 */
public final class MiniAppIdResolver {

    // 私有构造，禁止实例化工具类
    private MiniAppIdResolver() {
    }

    /**
     * 构建部门ID -> 部门信息映射，只过滤配置了主小程序/服务小程序的部门
     * @param depts 部门列表
     * @return Map<部门ID, 部门实体>
     */
    public static Map<Long, CompanyDept> buildDeptMiniAppMap(List<CompanyDept> depts) {
        if (depts == null || depts.isEmpty()) {
            return new HashMap<>();
        }
        return depts.stream()
                .filter(d -> StringUtils.isNotEmpty(d.getMiniAppMaster()) || StringUtils.isNotEmpty(d.getMiniAppServer()))
                // key重复保留第一个部门数据
                .collect(Collectors.toMap(CompanyDept::getDeptId, d -> d, (oldVal, newVal) -> oldVal));
    }

    /**
     * 构建用户ID -> 部门ID映射关系
     * @param users 企业用户列表
     * @return Map<用户ID, 部门ID>
     */
    public static Map<Long, Long> buildCompanyUserDeptMap(List<CompanyUser> users) {
        if (users == null || users.isEmpty()) {
            return new HashMap<>();
        }
        Map<Long, Long> map = new HashMap<>(users.size());
        for (CompanyUser user : users) {
            Long userId = user.getUserId();
            Long deptId = user.getDeptId();
            if (userId != null && deptId != null) {
                map.put(userId, deptId);
            }
        }
        return map;
    }

    /**
     * 根据用户ID获取所属部门ID
     * @param companyUserId 用户ID
     * @param companyUserDeptMap 用户-部门映射表
     * @return 部门ID，无匹配返回null
     */
    public static Long getDeptId(Long companyUserId, Map<Long, Long> companyUserDeptMap) {
        if (companyUserId == null || companyUserDeptMap == null) {
            return null;
        }
        return companyUserDeptMap.get(companyUserId);
    }

    /**
     * 解析最终可用小程序AppId
     * 优先级：部门自定义小程序 > 企业级通用小程序
     * @param deptId 部门ID
     * @param companyId 企业ID
     * @param listIndex 小程序类型下标 0=主小程序 1=服务小程序
     * @param sendMsgType 消息发送类型，仅等于1时读取企业通用小程序
     * @param miniMap 企业小程序总映射：key企业ID -> key消息类型 -> 小程序列表
     * @param deptMiniAppMap 带小程序配置的部门映射表
     * @return 匹配到的小程序AppId，无配置返回null
     */
    public static String resolveMiniAppId(Long deptId,
                                          Long companyId,
                                          int listIndex,
                                          Integer sendMsgType,
                                          Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap,
                                          Map<Long, CompanyDept> deptMiniAppMap) {
        // 1.优先读取部门单独配置的小程序
        if (deptId != null && deptMiniAppMap != null && !deptMiniAppMap.isEmpty()) {
            CompanyDept dept = deptMiniAppMap.get(deptId);
            if (dept != null) {
                String targetAppId = listIndex == 0 ? dept.getMiniAppMaster() : dept.getMiniAppServer();
                if (StringUtils.isNotEmpty(targetAppId)) {
                    return targetAppId;
                }
            }
        }

        // 消息类型非1、企业小程序映射为空、企业ID为空，直接返回空
        if (miniMap == null || miniMap.isEmpty() || sendMsgType == null || !sendMsgType.equals(1) || companyId == null) {
            return null;
        }

        // 2.读取企业统一配置的小程序
        Map<Integer, List<CompanyMiniapp>> typeMiniAppMap = miniMap.get(companyId);
        if (typeMiniAppMap == null) {
            return null;
        }

        List<CompanyMiniapp> miniAppList = typeMiniAppMap.get(listIndex);
        if (miniAppList == null || miniAppList.isEmpty()) {
            return null;
        }

        // 取列表第一条小程序配置
        CompanyMiniapp firstMiniApp = miniAppList.get(0);
        if (firstMiniApp != null && !StringUtil.strIsNullOrEmpty(firstMiniApp.getAppId())) {
            return firstMiniApp.getAppId();
        }
        return null;
    }
}
