package com.ruoyi.web.modules.industryservice.support;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysDeptService;

/**
 * 填报乡镇 / 村字典（县 → 乡镇 → 村；乡镇为县级下 order_num &gt; 12 节点）。
 * <p>
 * 下拉范围：
 * <ul>
 *   <li>乡镇人员：仅本镇 + 本镇下各村</li>
 *   <li>村级人员：仅上级乡镇 + 本村（不依赖 selectDeptList 的 @DataScope，避免查不到上级镇）</li>
 *   <li>其余（含超管）：按部门数据权限列出填报乡镇/村</li>
 * </ul>
 */
@Component
public class TownDeptSupport
{
    @Autowired
    private ISysDeptService deptService;

    public List<SysDept> listReportTowns()
    {
        ReportOrgScope scope = resolveReportOrgScope();
        if (scope.townDeptId != null)
        {
            SysDept town = deptService.selectDeptById(scope.townDeptId);
            if (isActiveReportTown(town))
            {
                return Collections.singletonList(town);
            }
            return Collections.emptyList();
        }
        return queryReportTownsByDataScope();
    }

    public List<SysDept> listVillagesUnderTown(Long townDeptId)
    {
        List<SysDept> villages = new ArrayList<>();
        if (townDeptId == null)
        {
            return villages;
        }
        ReportOrgScope scope = resolveReportOrgScope();
        if (scope.townDeptId != null && !scope.townDeptId.equals(townDeptId))
        {
            return villages;
        }
        if (scope.villageDeptId != null)
        {
            SysDept village = deptService.selectDeptById(scope.villageDeptId);
            if (isActiveDept(village) && townDeptId.equals(village.getParentId()))
            {
                villages.add(village);
            }
            return villages;
        }
        return queryVillagesByParent(townDeptId);
    }

    /**
     * 县 → 乡镇 → 村 树；仅叶子村可选（前端 disable-branch-nodes，父级不设 disabled 以免无法点选子节点）。
     */
    public List<TreeSelect> buildVillageTree()
    {
        List<TreeSelect> townNodes = new ArrayList<>();
        for (SysDept town : listReportTowns())
        {
            TreeSelect townNode = new TreeSelect();
            townNode.setId(town.getDeptId());
            townNode.setLabel(town.getDeptName());
            List<TreeSelect> children = new ArrayList<>();
            for (SysDept village : listVillagesUnderTown(town.getDeptId()))
            {
                TreeSelect villageNode = new TreeSelect();
                villageNode.setId(village.getDeptId());
                villageNode.setLabel(village.getDeptName());
                children.add(villageNode);
            }
            townNode.setChildren(children);
            townNodes.add(townNode);
        }

        SysDept county = deptService.selectDeptById(YakHerdInventoryRules.TOWN_PARENT_ID);
        TreeSelect countyNode = new TreeSelect();
        countyNode.setId(YakHerdInventoryRules.TOWN_PARENT_ID);
        countyNode.setLabel(county != null && StringUtils.isNotEmpty(county.getDeptName())
                ? county.getDeptName()
                : "巴青县");
        countyNode.setChildren(townNodes);

        List<TreeSelect> roots = new ArrayList<>();
        roots.add(countyNode);
        return roots;
    }

    public Map<String, SysDept> townNameMap()
    {
        Map<String, SysDept> map = new LinkedHashMap<>();
        for (SysDept town : listReportTowns())
        {
            if (StringUtils.isNotEmpty(town.getDeptName()))
            {
                map.put(town.getDeptName().trim(), town);
            }
        }
        return map;
    }

    public SysDept requireReportTown(Long townDeptId)
    {
        if (townDeptId == null)
        {
            return null;
        }
        for (SysDept town : listReportTowns())
        {
            if (townDeptId.equals(town.getDeptId()))
            {
                return town;
            }
        }
        return null;
    }

    /**
     * 校验村属于填报乡镇，并返回村部门。
     */
    public SysDept requireReportVillage(Long villageDeptId)
    {
        if (villageDeptId == null)
        {
            return null;
        }
        SysDept village = deptService.selectDeptById(villageDeptId);
        if (!isActiveDept(village))
        {
            return null;
        }
        if (requireReportTown(village.getParentId()) == null)
        {
            return null;
        }
        return village;
    }

    public SysDept resolveTownByName(String townName)
    {
        if (StringUtils.isEmpty(townName))
        {
            return null;
        }
        String normalized = normalizeTownName(townName.trim());
        SysDept town = townNameMap().get(normalized);
        if (town != null)
        {
            return town;
        }
        return townNameMap().get(townName.trim());
    }

    /**
     * 在指定乡镇下按村名解析村部门。
     */
    public SysDept resolveVillageByTownAndName(Long townDeptId, String villageName)
    {
        if (townDeptId == null || StringUtils.isEmpty(villageName))
        {
            return null;
        }
        String name = villageName.trim();
        for (SysDept village : listVillagesUnderTown(townDeptId))
        {
            if (name.equals(village.getDeptName()))
            {
                return village;
            }
        }
        return null;
    }

    /**
     * 模板乡镇名与 sys_dept 名称归一（如「扎色镇」→「杂色镇」）
     */
    public static String normalizeTownName(String townName)
    {
        if ("扎色镇".equals(townName))
        {
            return "杂色镇";
        }
        return townName;
    }

    public boolean isVillageUnderTown(Long villageDeptId, Long townDeptId)
    {
        if (villageDeptId == null)
        {
            return true;
        }
        if (townDeptId == null)
        {
            return false;
        }
        SysDept village = deptService.selectDeptById(villageDeptId);
        return village != null && "0".equals(village.getDelFlag()) && townDeptId.equals(village.getParentId());
    }

    public List<Map<String, Object>> toOptionList()
    {
        List<Map<String, Object>> options = new ArrayList<>();
        for (SysDept town : listReportTowns())
        {
            Map<String, Object> item = new LinkedHashMap<>();
            item.put("deptId", town.getDeptId());
            item.put("deptName", town.getDeptName());
            item.put("orderNum", town.getOrderNum());
            options.add(item);
        }
        return Collections.unmodifiableList(options);
    }

    /**
     * 大屏等全县场景：全部填报乡镇（不按登录人/数据权限收窄）。
     */
    public List<SysDept> listAllReportTowns()
    {
        SysDept query = new SysDept();
        query.setParentId(YakHerdInventoryRules.TOWN_PARENT_ID);
        query.setStatus("0");
        List<SysDept> depts = deptService.selectDeptListWithoutDataScope(query);
        List<SysDept> towns = new ArrayList<>();
        if (depts == null)
        {
            return towns;
        }
        for (SysDept dept : depts)
        {
            if (isActiveReportTown(dept))
            {
                towns.add(dept);
            }
        }
        towns.sort((a, b) -> Integer.compare(
                a.getOrderNum() == null ? 0 : a.getOrderNum(),
                b.getOrderNum() == null ? 0 : b.getOrderNum()));
        return towns;
    }

    /**
     * 大屏等全县场景：指定填报乡镇下全部村（不按登录人收窄）。
     */
    public List<SysDept> listAllVillagesUnderTown(Long townDeptId)
    {
        List<SysDept> villages = new ArrayList<>();
        if (townDeptId == null)
        {
            return villages;
        }
        SysDept town = deptService.selectDeptById(townDeptId);
        if (!isActiveReportTown(town))
        {
            return villages;
        }
        SysDept query = new SysDept();
        query.setParentId(townDeptId);
        query.setStatus("0");
        List<SysDept> depts = deptService.selectDeptListWithoutDataScope(query);
        if (depts == null)
        {
            return villages;
        }
        for (SysDept dept : depts)
        {
            if (isActiveDept(dept))
            {
                villages.add(dept);
            }
        }
        villages.sort((a, b) -> Integer.compare(
                a.getOrderNum() == null ? 0 : a.getOrderNum(),
                b.getOrderNum() == null ? 0 : b.getOrderNum()));
        return villages;
    }

    /**
     * 大屏等全县场景：县 → 乡镇 → 村树（不按登录人/数据权限收窄）。
     */
    public List<TreeSelect> buildAllVillageTree()
    {
        List<TreeSelect> townNodes = new ArrayList<>();
        for (SysDept town : listAllReportTowns())
        {
            TreeSelect townNode = new TreeSelect();
            townNode.setId(town.getDeptId());
            townNode.setLabel(town.getDeptName());
            List<TreeSelect> children = new ArrayList<>();
            for (SysDept village : listAllVillagesUnderTown(town.getDeptId()))
            {
                TreeSelect villageNode = new TreeSelect();
                villageNode.setId(village.getDeptId());
                villageNode.setLabel(village.getDeptName());
                children.add(villageNode);
            }
            townNode.setChildren(children);
            townNodes.add(townNode);
        }

        SysDept county = deptService.selectDeptById(YakHerdInventoryRules.TOWN_PARENT_ID);
        TreeSelect countyNode = new TreeSelect();
        countyNode.setId(YakHerdInventoryRules.TOWN_PARENT_ID);
        countyNode.setLabel(county != null && StringUtils.isNotEmpty(county.getDeptName())
                ? county.getDeptName()
                : "巴青县");
        countyNode.setChildren(townNodes);

        List<TreeSelect> roots = new ArrayList<>();
        roots.add(countyNode);
        return roots;
    }

    /**
     * 大屏等全县场景：乡镇下拉选项（不按登录人收窄）。
     */
    public List<Map<String, Object>> toAllOptionList()
    {
        List<Map<String, Object>> options = new ArrayList<>();
        for (SysDept town : listAllReportTowns())
        {
            Map<String, Object> item = new LinkedHashMap<>();
            item.put("deptId", town.getDeptId());
            item.put("deptName", town.getDeptName());
            item.put("orderNum", town.getOrderNum());
            options.add(item);
        }
        return Collections.unmodifiableList(options);
    }

    /**
     * 当前登录人锁定的填报乡镇 id（乡镇/村人员）；非此类人员返回 null（不限制）。
     */
    public Long resolveScopedTownDeptId()
    {
        return resolveReportOrgScope().townDeptId;
    }

    /**
     * 当前登录人是否落在填报乡镇/村：返回应锁定的乡镇、村；否则不限制（走 @DataScope 列表）。
     */
    ReportOrgScope resolveReportOrgScope()
    {
        LoginUser loginUser = tryGetLoginUser();
        if (loginUser == null || SecurityUtils.isAdmin(loginUser.getUserId()))
        {
            return ReportOrgScope.unrestricted();
        }
        Long deptId = loginUser.getDeptId();
        if (deptId == null && loginUser.getUser() != null)
        {
            deptId = loginUser.getUser().getDeptId();
        }
        if (deptId == null)
        {
            return ReportOrgScope.unrestricted();
        }
        SysDept self = deptService.selectDeptById(deptId);
        if (!isActiveDept(self))
        {
            return ReportOrgScope.unrestricted();
        }
        if (isActiveReportTown(self))
        {
            return ReportOrgScope.townOnly(self.getDeptId());
        }
        if (self.getParentId() != null)
        {
            SysDept parent = deptService.selectDeptById(self.getParentId());
            if (isActiveReportTown(parent))
            {
                return ReportOrgScope.villageOnly(parent.getDeptId(), self.getDeptId());
            }
        }
        return ReportOrgScope.unrestricted();
    }

    private List<SysDept> queryReportTownsByDataScope()
    {
        SysDept query = new SysDept();
        query.setParentId(YakHerdInventoryRules.TOWN_PARENT_ID);
        query.setStatus("0");
        List<SysDept> depts = deptService.selectDeptList(query);
        List<SysDept> towns = new ArrayList<>();
        if (depts == null)
        {
            return towns;
        }
        for (SysDept dept : depts)
        {
            if (isActiveReportTown(dept))
            {
                towns.add(dept);
            }
        }
        towns.sort((a, b) -> Integer.compare(
                a.getOrderNum() == null ? 0 : a.getOrderNum(),
                b.getOrderNum() == null ? 0 : b.getOrderNum()));
        return towns;
    }

    private List<SysDept> queryVillagesByParent(Long townDeptId)
    {
        List<SysDept> villages = new ArrayList<>();
        SysDept query = new SysDept();
        query.setParentId(townDeptId);
        query.setStatus("0");
        List<SysDept> depts = deptService.selectDeptList(query);
        if (depts == null)
        {
            return villages;
        }
        for (SysDept dept : depts)
        {
            if (isActiveDept(dept))
            {
                villages.add(dept);
            }
        }
        villages.sort((a, b) -> Integer.compare(
                a.getOrderNum() == null ? 0 : a.getOrderNum(),
                b.getOrderNum() == null ? 0 : b.getOrderNum()));
        return villages;
    }

    static boolean isActiveReportTown(SysDept dept)
    {
        if (!isActiveDept(dept))
        {
            return false;
        }
        if (!Long.valueOf(YakHerdInventoryRules.TOWN_PARENT_ID).equals(dept.getParentId()))
        {
            return false;
        }
        return dept.getOrderNum() != null && dept.getOrderNum() > YakHerdInventoryRules.TOWN_MIN_ORDER_NUM;
    }

    static boolean isActiveDept(SysDept dept)
    {
        return dept != null && "0".equals(dept.getDelFlag()) && "0".equals(dept.getStatus());
    }

    private static LoginUser tryGetLoginUser()
    {
        try
        {
            return SecurityUtils.getLoginUser();
        }
        catch (Exception e)
        {
            return null;
        }
    }

    static final class ReportOrgScope
    {
        final Long townDeptId;
        final Long villageDeptId;

        private ReportOrgScope(Long townDeptId, Long villageDeptId)
        {
            this.townDeptId = townDeptId;
            this.villageDeptId = villageDeptId;
        }

        static ReportOrgScope unrestricted()
        {
            return new ReportOrgScope(null, null);
        }

        static ReportOrgScope townOnly(Long townDeptId)
        {
            return new ReportOrgScope(townDeptId, null);
        }

        static ReportOrgScope villageOnly(Long townDeptId, Long villageDeptId)
        {
            return new ReportOrgScope(townDeptId, villageDeptId);
        }
    }
}
