package jnpf.authority.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.authority.mapper.FtbPermissionFunctionMenuMapper;
import jnpf.authority.mapper.FtbPermissionRoleMenuRelationMapper;
import jnpf.authority.service.FtbPermissionFunctionMenuService;
import jnpf.base.ModuleApi;
import jnpf.base.SystemApi;
import jnpf.base.entity.ModuleEntity;
import jnpf.base.entity.SystemEntity;
import jnpf.base.model.module.MenuListVO;
import jnpf.base.vo.PageListVO;
import jnpf.model.UserMenuModel;
import jnpf.model.authority.dto.menu.FtbPermissionFunctionMenuDTO;
import jnpf.model.authority.dto.menu.FtbPermissionMenuDirectoryDTO;
import jnpf.model.authority.po.FtbPermissionFunctionMenu;
import jnpf.model.authority.po.FtbPermissionRoleMenuRelation;
import jnpf.model.authority.vo.menu.FtbPermissionFunctionMenuVO;
import jnpf.model.authority.vo.menu.FtbPermissionMenuConfigTree;
import jnpf.model.authority.vo.menu.FtbPermissionMenuConfigTreeVO;
import jnpf.model.authority.vo.menu.FtbPermissionMenuDirectoryVO;
import jnpf.model.authority.vo.role.FtbPermissionRoleInfoVO;
import jnpf.model.cultivate.CultivatePage;
import jnpf.util.JsonUtil;
import jnpf.util.UserProvider;
import jnpf.util.treeutil.SumTree;
import jnpf.util.treeutil.newtreeutil.TreeDotUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 *
 *
 *@Author: peng.hao
 *@create: 2025/3/5
 *
 */
@Service
public class FtbPermissionFunctionMenuServiceImpl extends ServiceImpl<FtbPermissionFunctionMenuMapper, FtbPermissionFunctionMenu> implements FtbPermissionFunctionMenuService {

    @Resource
    private FtbPermissionFunctionMenuMapper ftbPermissionFunctionMenuMapper;

    @Resource
    private SystemApi systemApi;

    @Resource
    private ModuleApi moduleApi;

    @Resource
    private FtbPermissionRoleMenuRelationMapper ftbPermissionRoleMenuRelationMapper;

    @Override
    public PageListVO<FtbPermissionFunctionMenuVO> getAListOfSubPages(String menuId, CultivatePage page) {
        Page<FtbPermissionFunctionMenuVO> objectPage = page.coverCultivatePage();
        Page<FtbPermissionFunctionMenuVO> menuPage = ftbPermissionFunctionMenuMapper.getAListOfSubPages(objectPage, menuId);
        return CultivatePage.coverPageList(menuPage);
    }

    @Override
    public void addAListOfSubPages(FtbPermissionFunctionMenuDTO dto) {
        String enCode = dto.getEnCode();
        LambdaQueryWrapper<FtbPermissionFunctionMenu> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPermissionFunctionMenu::getFuncCoding, enCode);
        queryWrapper.eq(FtbPermissionFunctionMenu::getEnableMark, 0);
        Long aLong = baseMapper.selectCount(queryWrapper);
        if (aLong > 0) {
            throw new RuntimeException("编码重复");
        }
        baseMapper.insert(FtbPermissionFunctionMenuDTO.convert(dto));
    }

    @Override
    public void updateAListOfSubPages(FtbPermissionFunctionMenuDTO dto) {
        String enCode = dto.getEnCode();
        LambdaQueryWrapper<FtbPermissionFunctionMenu> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPermissionFunctionMenu::getFuncCoding, enCode);
        queryWrapper.eq(FtbPermissionFunctionMenu::getEnableMark, 0);
        queryWrapper.ne(FtbPermissionFunctionMenu::getId, dto.getId());
        Long aLong = baseMapper.selectCount(queryWrapper);
        if (aLong > 0) {
            throw new RuntimeException("编码重复");
        }
        baseMapper.updateById(FtbPermissionFunctionMenuDTO.convert(dto));
    }

    @Override
    public List<MenuListVO> getAListOfMenus(String category, String keyword) {
        SystemEntity systemVO = systemApi.getSystemVO();
        String systemId = systemVO.getId();
        String tenantId = UserProvider.getUser().getTenantId();
        List<ModuleEntity> data = moduleApi.getListWithoutSystemId(systemId, category, keyword, tenantId);
        if (CollUtil.isEmpty(data)) {
            return new ArrayList<>();
        }
        List<MenuListVO> jsonToList;
        if (StringUtils.isNotEmpty(keyword)){
            jsonToList = getTheDataset(data);
        }else {
            List<UserMenuModel> list = JsonUtil.getJsonToList(data, UserMenuModel.class);
            List<SumTree<UserMenuModel>> menuList = TreeDotUtils.convertListToTreeDot(list, "-1");
            jsonToList= JsonUtil.getJsonToList(menuList, MenuListVO.class);
        }
        return jsonToList;
    }

    public static final Set<String> EXCLUDED_DIRECTORIES = Set.of(
            "资料库", "权限管理"
    );
    @Override
    public List<FtbPermissionMenuDirectoryVO> getAListOfMenuDirectory(String roleId) {
        SystemEntity systemVO = systemApi.getSystemVO();
        String systemId = systemVO.getId();
        String tenantId = UserProvider.getUser().getTenantId();
        FtbPermissionRoleInfoVO vo = new FtbPermissionRoleInfoVO();
        if (roleId != null ){
            vo = baseMapper.getRoleWithMenu(roleId);
        }
        List<ModuleEntity> data = moduleApi.getListWithoutSystemId(systemId, null, null, tenantId);
        // 获取顶级目录菜单
        List<ModuleEntity> entities = data.stream().filter(item -> item.getType() != null && item.getEnabledMark() != null   && 1 == item.getEnabledMark() && "-1".equals(item.getParentId())).collect(Collectors.toList());
        List<FtbPermissionMenuDirectoryVO> directoryVOS = entities.stream().map(FtbPermissionMenuDirectoryVO::convert).distinct().collect(Collectors.toList());
        for (FtbPermissionMenuDirectoryVO directoryVO : directoryVOS) {
            List<FtbPermissionMenuDirectoryVO.FtbPermissionMenuDirectoryInfoVO> infoVOS = entities.stream().filter(v -> v.getFullName().equals(directoryVO.getFullName())).map(v -> {
                FtbPermissionMenuDirectoryVO.FtbPermissionMenuDirectoryInfoVO infoVO = new FtbPermissionMenuDirectoryVO.FtbPermissionMenuDirectoryInfoVO();
                String vCategory = v.getCategory();
                String vId = v.getId();
                infoVO.setId(vId);
                infoVO.setCategory(vCategory);
                return infoVO;
            }).collect(Collectors.toList());
            if (StringUtils.isNotEmpty(roleId) && vo != null) {
                List<String> functionIds  = new ArrayList<>();
                if ( vo.getFunctionWebId() != null ){
                    String[] split = vo.getFunctionWebId().split(",");
                    functionIds .addAll(List.of(split));
                }
                if ( vo.getFunctionAppId() != null ){
                    functionIds.addAll(List.of(vo.getFunctionAppId().split(",")));
                }
                if (vo.getFunctionPcId() != null) {
                    functionIds.addAll(List.of(vo.getFunctionPcId().split(",")));
                }
                // 拼接并过滤非空字段
                functionIds.removeIf(StrUtil::isBlank);
                List<String> fullNames = entities.stream()
                        .filter(item -> functionIds.contains(item.getId()))
                        .map(ModuleEntity::getFullName).distinct().collect(Collectors.toList());
                if (fullNames.contains(directoryVO.getFullName())) {
                    directoryVO.setIsUse(true);
                }
            }
            directoryVO.setChildren(infoVOS);
        }
        return directoryVOS.stream()
                .filter(item -> !EXCLUDED_DIRECTORIES.contains(item.getFullName()))
                .collect(Collectors.toList());

    }

    @Override
    public List<FtbPermissionMenuConfigTreeVO> getAListOfFunctionMenuConfigurations(FtbPermissionMenuDirectoryDTO dto) {
        String tenantId = UserProvider.getUser().getTenantId();
        if (StrUtil.isBlank(tenantId)) {
            tenantId = dto.getTenantId();
        }
        ModuleEntity data = moduleApi.getModuleByList(dto.getId());
        if (ObjectUtils.isEmpty(data)){
            return null;
        }
        String id =data.getId();
        // 查询所有子集
        List<ModuleEntity> newData = new ArrayList<>();
        getTreeMenuWithPreantId(id, tenantId,newData);
        List<UserMenuModel> list = JsonUtil.getJsonToList(newData, UserMenuModel.class);
        List<SumTree<UserMenuModel>> menuList = TreeDotUtils.convertListToTreeDot(list);
        List<MenuListVO> toList = JsonUtil.getJsonToList(menuList, MenuListVO.class);
        // 根据所有的子集查询是否配置的菜单且需要递归获取配置进行复原
        List<FtbPermissionMenuConfigTree> configTrees = new ArrayList<>();
        buildMenuDetails(toList,configTrees);
        if (dto.getRoleId() != null){
            // 查询当前角色的菜单配置
            LambdaQueryWrapper<FtbPermissionRoleMenuRelation> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(FtbPermissionRoleMenuRelation::getRoleId, dto.getRoleId());
            List<FtbPermissionRoleMenuRelation> relations = ftbPermissionRoleMenuRelationMapper.selectList(wrapper);
            configTrees.forEach(item -> {
                boolean anyMatch = relations.stream().anyMatch(relation -> relation.getRoleMenuId().equals(item.getId()));
                if (anyMatch) {
                    item.setIsChecked(true);
                }
            });
        }
        List<SumTree<FtbPermissionMenuConfigTree>> trees = TreeDotUtils.convertListToTreeDot(configTrees);
        return JsonUtil.getJsonToList(trees, FtbPermissionMenuConfigTreeVO.class);
    }

    @Override
    public List<FtbPermissionFunctionMenuVO> querySubpageButton(String subPageId) {
        LambdaQueryWrapper<FtbPermissionFunctionMenu> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FtbPermissionFunctionMenu::getParentId, subPageId);
        wrapper.eq(FtbPermissionFunctionMenu::getFunType,1);
        List<FtbPermissionFunctionMenu> functionMenus = baseMapper.selectList(wrapper);
        return functionMenus.stream().map(FtbPermissionFunctionMenuVO::convert).collect(Collectors.toList());
    }

    public void buildMenuDetails(List<MenuListVO> newData, List<FtbPermissionMenuConfigTree> list){
        for (MenuListVO moduleEntity : newData) {
            String id = moduleEntity.getId();
            FtbPermissionMenuConfigTree configTree = new FtbPermissionMenuConfigTree();
            configTree.setId(id);
            configTree.setName(moduleEntity.getFullName());
            configTree.setParentId(moduleEntity.getParentId());
            configTree.setModuleType(moduleEntity.getType());
            list.add(configTree);
            // 查询当前菜单是否配置了子页面
            LambdaQueryWrapper<FtbPermissionFunctionMenu> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(FtbPermissionFunctionMenu::getFunType,0);
            queryWrapper.eq(FtbPermissionFunctionMenu::getParentId,id);
            List<FtbPermissionFunctionMenu> functionMenuList = baseMapper.selectList(queryWrapper);
            if (CollUtil.isNotEmpty(functionMenuList)){
                // 查询当前菜单是否有子集
                list.addAll(functionMenuList.stream().map(FtbPermissionMenuConfigTree::convert).collect(Collectors.toList()));
                for (FtbPermissionFunctionMenu functionMenu : functionMenuList) {
                    LambdaQueryWrapper<FtbPermissionFunctionMenu> menuLambdaQueryWrapper = Wrappers.lambdaQuery();
                    menuLambdaQueryWrapper.eq(FtbPermissionFunctionMenu::getFunType,1);
                    menuLambdaQueryWrapper.eq(FtbPermissionFunctionMenu::getParentId,functionMenu.getId());
                    List<FtbPermissionFunctionMenu> buttonList = baseMapper.selectList(menuLambdaQueryWrapper);
                    if (CollUtil.isNotEmpty(buttonList)){
                        list.addAll(buttonList.stream().map(FtbPermissionMenuConfigTree::convert).collect(Collectors.toList()));
                    }
                }
            }else if (moduleEntity.getChildren() != null){
                // 子集递归
                List<MenuListVO> children = moduleEntity.getChildren();
                buildMenuDetails(children, list);
            }
        }

    }


    /**
     * 查询子集
     * @param meuId
     * @param tenantId
     * @param data
     */
    private void getTreeMenuWithPreantId(String meuId, String tenantId,List<ModuleEntity> data){
        List<ModuleEntity> moduleEntityList = moduleApi.findAllSubsetsBasedOnParent(meuId,tenantId);
        if (CollUtil.isNotEmpty(moduleEntityList)){
            data.addAll(moduleEntityList);
            moduleEntityList.forEach(vo->{
                getTreeMenuWithPreantId(vo.getId(),tenantId,data);
            });
        }
    }

    public List<MenuListVO> getTheDataset(List<ModuleEntity> data){
        List<ModuleEntity> result = new ArrayList<>();
        for (ModuleEntity datum : data) {
            result.add(datum);
            if (!datum.getParentId().equals("-1")) {
                getTopModule(result, datum.getParentId());
            }
        }
        List<ModuleEntity> entities = result.stream().distinct().collect(Collectors.toList());
        List<UserMenuModel> list = JsonUtil.getJsonToList(entities, UserMenuModel.class);
        List<SumTree<UserMenuModel>> menuList = TreeDotUtils.convertListToTreeDot(list);
        return JsonUtil.getJsonToList(menuList, MenuListVO.class);

    }
    private void getTopModule(List<ModuleEntity> data,String peuId){
        String tenantId = UserProvider.getUser().getTenantId();
       ModuleEntity byParentId = moduleApi.getTenantInfoById(peuId, tenantId);
        if (ObjectUtils.isNotEmpty(byParentId)){
            data.add(byParentId);
                if (!byParentId.getParentId().equals("-1")) {
                    getTopModule(data, byParentId.getParentId());
                }
        }
    }
}
