package com.usky.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.system.domain.*;
import com.usky.system.mapper.SysPlatformMenuMapper;
import com.usky.system.mapper.SysTenantPlatformMapper;
import com.usky.system.service.SysMobileTenantMenuService;
import com.usky.system.service.SysPlatformMenuService;
import com.usky.system.service.SysTenantMenuService;
import com.usky.system.service.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 平台和菜单关联表 服务实现类
 * </p>
 *
 * @author ya
 * @since 2022-05-18
 */
@Service
public class SysPlatformMenuServiceImpl extends AbstractCrudService<SysPlatformMenuMapper, SysPlatformMenu> implements SysPlatformMenuService {

    @Autowired
    private SysTenantMenuService sysTenantMenuService;

    @Autowired
    private SysTenantPlatformMapper sysTenantPlatformMapper;

    @Autowired
    private SysMobileTenantMenuService sysMobileTenantMenuService;

    public List<SysMenu> getPlatformMenuList(Integer platformId){
        return baseMapper.getMenuList(platformId, null);
    }

    public List<SysMobileMenu> getMobilePlatformMenuList(Integer tenantId){
        LambdaQueryWrapper<SysTenantPlatform> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SysTenantPlatform::getTenantId,tenantId);
        List<SysTenantPlatform> list = sysTenantPlatformMapper.selectList(queryWrapper);
        List<Integer> platformIds = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (int j = 0; j < list.size(); j++) {
                platformIds.add(list.get(j).getPlatformId());
            }
        }
        return baseMapper.getMobileMenuList(platformIds, null);
    }

    public Long[] selectPlatformMenu(Integer tenantId){
        LambdaQueryWrapper<SysTenantMenu> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SysTenantMenu::getTenantId, tenantId).orderByAsc(SysTenantMenu::getMenuId);
        List<SysTenantMenu> menuList = sysTenantMenuService.list(queryWrapper);
        Long[] arr = new Long[menuList.size()];
        for (int i = 0; i < menuList.size(); i++) {
            arr[i] = menuList.get(i).getMenuId();
        }
        return arr;
    }

    public Long[] selectMobilePlatformMenu(Integer tenantId){
        LambdaQueryWrapper<SysMobileTenantMenu> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SysMobileTenantMenu::getTenantId, tenantId).orderByAsc(SysMobileTenantMenu::getMenuId);
        List<SysMobileTenantMenu> menuList = sysMobileTenantMenuService.list(queryWrapper);
        Long[] arr = new Long[menuList.size()];
        for (int i = 0; i < menuList.size(); i++) {
            arr[i] = menuList.get(i).getMenuId();
        }
        return arr;
    }


    public Map<String, Object> getMenuList(Integer platformId, Integer tenantId) {
        //全部目录查询
        List<SysMenu> sysMenuListTwo = baseMapper.getMenuList(platformId, "M");
        //全部菜单查询
        List<SysMenu> sysMenuListOne = baseMapper.getMenuList(platformId, "C");
        //全部按钮列表
        List<SysMenu> sysMenuListThree = baseMapper.getMenuList(platformId, "F");
        //已选中按钮列表

        LambdaQueryWrapper<SysTenantMenu> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SysTenantMenu::getTenantId, tenantId);
        List<SysTenantMenu> sysMenuListFour = sysTenantMenuService.list(queryWrapper);

        List<SysTenantMenu> menuList = baseMapper.getMenuListOne(tenantId, "F");
        Long[] arr = new Long[menuList.size()];
        for (int i = 0; i < menuList.size(); i++) {
            arr[i] = menuList.get(i).getMenuId();
        }


        List<SysMenuTwoVo> sysMenuVoListOne = new ArrayList<>();
        List<SysMenuOneVo> SysMenuVoList = new ArrayList<>();
        List<SysMenuVo> SysMenuVoListOne = new ArrayList<>();
        List<Object> list = new ArrayList<>();
//        if (sysMenuListFour.size()>0){
        for (int i = 0; i < sysMenuListThree.size(); i++) {
            SysMenuTwoVo sysMenuTwoVo = new SysMenuTwoVo();
            sysMenuTwoVo.setId(sysMenuListThree.get(i).getMenuId());
            sysMenuTwoVo.setName(sysMenuListThree.get(i).getMenuName());
            sysMenuTwoVo.setFid(sysMenuListThree.get(i).getParentId());
            long Id = sysMenuListThree.get(i).getMenuId();
            sysMenuTwoVo.setChecked(false);
            if (sysMenuListFour.size() > 0) {
                for (int j = 0; j < sysMenuListFour.size(); j++) {
                    long MenuId = sysMenuListFour.get(j).getMenuId();
                    if (Id == MenuId) {
                        sysMenuTwoVo.setChecked(true);
                    }
                }
            } else {
                sysMenuTwoVo.setChecked(false);
            }

            sysMenuVoListOne.add(sysMenuTwoVo);
        }
        for (int i = 0; i < sysMenuListOne.size(); i++) {
            SysMenuOneVo sysMenuOneVo = new SysMenuOneVo();
            sysMenuOneVo.setId(sysMenuListOne.get(i).getMenuId());
            sysMenuOneVo.setMenu(sysMenuListOne.get(i).getMenuName());
            sysMenuOneVo.setFid(sysMenuListOne.get(i).getParentId());
            long id = sysMenuListOne.get(i).getMenuId();
            List<SysMenuTwoVo> sysMenuVoListTwo = new ArrayList<>();
            List<SysMenuTwoVo> menuListTrue = new ArrayList<>();
            for (int j = 0; j < sysMenuVoListOne.size(); j++) {
                long FId = sysMenuVoListOne.get(j).getFid();
                Boolean pd = sysMenuVoListOne.get(j).getChecked();
                if (id == FId) {
                    sysMenuVoListTwo.add(sysMenuVoListOne.get(j));
                    if (pd == true) {
                        menuListTrue.add(sysMenuVoListOne.get(j));
                    }
                }
            }
            sysMenuOneVo.setAuthority(sysMenuVoListTwo);
            if (menuListTrue.size() > 0) {
                sysMenuOneVo.setChecked(true);
            } else {
                sysMenuOneVo.setChecked(false);
            }
            SysMenuVoList.add(sysMenuOneVo);
        }

        for (int i = 0; i < sysMenuListTwo.size(); i++) {
            SysMenuVo sysMenuVo = new SysMenuVo();
            sysMenuVo.setId(sysMenuListTwo.get(i).getMenuId());
            sysMenuVo.setMenu(sysMenuListTwo.get(i).getMenuName());
            sysMenuVo.setFid(sysMenuListTwo.get(i).getParentId());
            long id = sysMenuListTwo.get(i).getMenuId();
            List<SysMenuOneVo> SysMenuVoListThree = new ArrayList<>();
            List<SysMenuOneVo> menuListtrueOne = new ArrayList<>();
            for (int j = 0; j < SysMenuVoList.size(); j++) {
                long FId = SysMenuVoList.get(j).getFid();
                Boolean pd = SysMenuVoList.get(j).getChecked();
                if (id == FId) {
                    SysMenuVoListThree.add(SysMenuVoList.get(j));
                    if (pd == true) {
                        menuListtrueOne.add(SysMenuVoList.get(j));
                    }
                }
            }
            sysMenuVo.setChildren(SysMenuVoListThree);
            if (menuListtrueOne.size() > 0) {
                sysMenuVo.setChecked(true);
            } else {
                sysMenuVo.setChecked(false);
            }

            SysMenuVoListOne.add(sysMenuVo);
        }

        for (int i = 0; i < SysMenuVoListOne.size(); i++) {
            String name = SysMenuVoListOne.get(i).getMenu();
            if (name.equals("数据管理") || name.equals("电能质量") || name.equals("系统管理") || name.equals("租户管理") || name.equals("统计管理")) {
                list.add(SysMenuVoListOne.get(i));
            } else {
                for (int j = 0; j < SysMenuVoList.size(); j++) {
                    String name2 = SysMenuVoList.get(j).getMenu();
                    if (name.equals(name2)) {
                        list.add(SysMenuVoList.get(j));
                    }
                }
            }
        }
//        }
        Map<String, Object> ajax = new HashMap<>();
        ajax.put("checkedKeys", arr);
        ajax.put("menus", list);

        return ajax;
    }


    @Override
    @Transactional
    public void updateMenu(TenantMenuVo tenantMenuVo) {
        Long tenantId = tenantMenuVo.getTenantId();
        Long[] selectedMenuIds = tenantMenuVo.getMenuIds();

        // 基础参数校验，避免无效数据库操作
        if (tenantId == null || selectedMenuIds == null || selectedMenuIds.length == 0) {
            // 若需清空该租户全部菜单，可放开下方注释；默认无选中则不做变更
            // sysTenantMenuService.remove(Wrappers.lambdaQuery(SysTenantMenu.class).eq(SysTenantMenu::getTenantId, tenantId));
            return;
        }

        // ========== 1. 收集全量授权菜单ID（按钮+各级父目录，Set天然去重） ==========
        Set<Long> allMenuIdSet = new HashSet<>();
        // 加入原始选中的菜单ID
        allMenuIdSet.addAll(Arrays.asList(selectedMenuIds));

        // 查询选中ID中类型为F的菜单，提取一级父目录ID
        List<SysMenu> fTypeMenuList = baseMapper.getMenuIdList(selectedMenuIds, "F");
        List<Long> firstLevelParentIds = fTypeMenuList.stream()
                .map(SysMenu::getParentId)
                .collect(Collectors.toList());

        // 存在一级父目录时，继续向上查询二级父目录
        if (!firstLevelParentIds.isEmpty()) {
            allMenuIdSet.addAll(firstLevelParentIds);
            // 查询一级父目录（C类型）的上级ID
            List<SysMenu> cTypeMenuList = baseMapper.getMenuIdList(firstLevelParentIds.toArray(new Long[0]), "C");
            List<Long> secondLevelParentIds = cTypeMenuList.stream()
                    .map(SysMenu::getParentId)
                    .collect(Collectors.toList());
            allMenuIdSet.addAll(secondLevelParentIds);
        }

        // 查询选中ID中类型为C的菜单，提取其父目录ID并加入集合
        List<SysMenu> selectedCTypeMenuList = baseMapper.getMenuIdList(selectedMenuIds, "C");
        List<Long> selectedCParentIds = selectedCTypeMenuList.stream()
                .map(SysMenu::getParentId)
                .collect(Collectors.toList());
        allMenuIdSet.addAll(selectedCParentIds);

        // ========== 2. 计算数据差异 ==========
        // 查询当前租户已有的菜单关联
        List<SysTenantMenu> existMenuList = sysTenantMenuService.list(
                Wrappers.lambdaQuery(SysTenantMenu.class)
                        .eq(SysTenantMenu::getTenantId, tenantId)
                        .select(SysTenantMenu::getMenuId)
        );
        Set<Long> existMenuIds = existMenuList.stream()
                .map(SysTenantMenu::getMenuId)
                .collect(Collectors.toSet());

        // 需删除：数据库已存在、新授权列表中没有的冗余关联
        List<Long> deleteMenuIds = existMenuList.stream()
                .map(SysTenantMenu::getMenuId)
                .filter(menuId -> !allMenuIdSet.contains(menuId))
                .collect(Collectors.toList());

        // 需新增：新授权列表中有、数据库不存在的关联
        List<SysTenantMenu> saveMenuList = allMenuIdSet.stream()
                .filter(menuId -> !existMenuIds.contains(menuId))
                .map(menuId -> {
                    SysTenantMenu sysTenantMenu = new SysTenantMenu();
                    sysTenantMenu.setTenantId(tenantId);
                    sysTenantMenu.setMenuId(menuId);
                    return sysTenantMenu;
                })
                .collect(Collectors.toList());

        // ========== 3. 执行数据库操作 ==========
        // 精准删除冗余关联
        if (!deleteMenuIds.isEmpty()) {
            sysTenantMenuService.remove(
                    Wrappers.lambdaQuery(SysTenantMenu.class)
                            .eq(SysTenantMenu::getTenantId, tenantId)
                            .in(SysTenantMenu::getMenuId, deleteMenuIds)
            );
        }

        // 批量新增缺失关联
        if (!saveMenuList.isEmpty()) {
            sysTenantMenuService.saveBatch(saveMenuList);
        }
    }

    @Transactional
    public void updateMobileMenu(MobileTenantMenuVO mobileTenantMenuVO) {
        List arr3 = new ArrayList();
        Long[] arr = mobileTenantMenuVO.getMenuIds();
        //菜单ID
        List<SysMobileMenu> menuIdList = baseMapper.getMobileMenuIdList(arr, "F");
        Long arr1[] = new Long[menuIdList.size()];
        for (int i = 0; i < menuIdList.size(); i++) {
            arr1[i] = menuIdList.get(i).getParentId();
        }
        //目录ID
        if(arr1.length > 0){
            List<SysMobileMenu> menuIdListOne = baseMapper.getMobileMenuIdList(arr1, "C");
            Long arr2[] = new Long[menuIdListOne.size()];
            for (int i = 0; i < menuIdListOne.size(); i++) {
                arr2[i] = menuIdListOne.get(i).getParentId();
            }
            List<SysMobileMenu> menuIdListTwo = baseMapper.getMobileMenuIdList(arr, "C");
            Long arr4[] = new Long[menuIdListTwo.size()];
            for (int i = 0; i < menuIdListTwo.size(); i++) {
                arr4[i] = menuIdListTwo.get(i).getParentId();
            }
            Long[] arr5 = arrayMerge(arr1, arr2);
            Long[] arr6 = arrayMerge(arr5, arr4);
            Long[] arr7 = arrayMerge(arr6, arr);
            for (int i = 0; i < arr7.length; i++) {
                if (!arr3.contains(arr7[i])) {
                    arr3.add(arr7[i]);
                }
            }
        }else{
            List<SysMobileMenu> menuIdListTwo = baseMapper.getMobileMenuIdList(arr, "C");
            Long arr4[] = new Long[menuIdListTwo.size()];
            for (int i = 0; i < menuIdListTwo.size(); i++) {
                arr4[i] = menuIdListTwo.get(i).getParentId();
            }
            Long[] arr7 = arrayMerge(arr4, arr);
            for (int i = 0; i < arr7.length; i++) {
                if (!arr3.contains(arr7[i])) {
                    arr3.add(arr7[i]);
                }
            }
        }

        // 删除租户菜单关联
        baseMapper.deleteMobileTenantMenuBy(mobileTenantMenuVO.getTenantId());
        //新增菜单
        if (arr3.size() > 0) {
            for (int i = 0; i < arr3.size(); i++) {
                SysMobileTenantMenu sysMobileTenantMenu = new SysMobileTenantMenu();
                sysMobileTenantMenu.setMenuId((Long) arr3.get(i));
                sysMobileTenantMenu.setTenantId(mobileTenantMenuVO.getTenantId());
                sysMobileTenantMenuService.save(sysMobileTenantMenu);
            }
        }
    }

    public Long[] arrayMerge(Long[] arr1, Long[] arr2) {
        Long arr3[] = new Long[arr1.length + arr2.length];
        for (int i = 0; i < arr1.length; i++) {
            arr3[i] = arr1[i];
        }
        for (int i = 0; i < arr2.length; i++) {
            arr3[i + arr1.length] = arr2[i];
        }
        return arr3;
    }

    public Object[] ifRepeat2(Object[] arr) {
        //创建一个集合
        List list = new ArrayList();
        //遍历数组往集合里存元素
        for (int i = 0; i < arr.length; i++) {
            //如果集合里面没有相同的元素才往里存
            if (!list.contains(arr[i])) {
                list.add(arr[i]);
            }
        }

        //toArray()方法会返回一个包含集合所有元素的Object类型数组
        Object[] newArr = list.toArray();
        return newArr;

    }
}