package thyyxxk.webserver.service.settings;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.dao.his.settings.MenuSettingsDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.login.UserInfo;
import thyyxxk.webserver.entity.settings.IntergrationMenu;
import thyyxxk.webserver.entity.settings.IntergrationPlatformRoleMenu;
import thyyxxk.webserver.service.RedisServer;
import thyyxxk.webserver.service.redislike.RedisLikeService;
import thyyxxk.webserver.utils.DynamicDataUtil;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.TokenUtil;
import thyyxxk.webserver.utils.TreeUtil;

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

@Service
@Slf4j
public class MenuSettingsService {
    private final MenuSettingsDao dao;
    private final RedisServer redisServer;
    private final RedisLikeService redisLikeService;

    @Value("${spring.redis.host}")
    private String redisUrl = "";

    @Value("${spring.datasource.dynamic.primary}")
    private String currentDbName = "";

    public MenuSettingsService(MenuSettingsDao dao,
                               RedisServer redisServer,
                               RedisLikeService redisLikeService) {
        this.dao = dao;
        this.redisServer = redisServer;
        this.redisLikeService = redisLikeService;
    }

    public void menuPushRedis() {
        String redisProdUrl = "172.16.32.167";
        String dbName = redisProdUrl.equals(redisUrl) ? "his" : currentDbName;
        List<IntergrationMenu> list = DynamicDataUtil.db(dbName, dao::getAll);
        redisServer.setData("IntergrationPlatformMenu", list);
    }

    public List<IntergrationMenu> getMenuSettings() {
        return menuListByTree(dao.getAll());
    }

    public List<IntergrationMenu> getUserMenu() {
        return getRedisMenuByCode(TokenUtil.getInstance().getTokenUserId());
    }

    public List<IntergrationMenu> getUserMenu(String code) {
        return getRedisMenuByCode(code);
    }

    private List<IntergrationMenu> menuListByTree(List<IntergrationMenu> list) {
        List<IntergrationMenu> res = TreeUtil.objectTree(list, (parent, child) -> {
            if (parent == null) {
                child.setCompletePath(child.getPath());
            } else {
                child.getCascaders().addAll(parent.getCascaders());
                child.getCascaders().add(child.getParentId());
                child.setCompletePath(parent.getCompletePath() + "/" + child.getPath());
            }
        });
        return TreeUtil.objectSort(res, "sort");
    }

    private List<IntergrationMenu> findParentMenus(List<IntergrationMenu> list, IntergrationMenu item) {
        List<IntergrationMenu> result = new ArrayList<>();
        for (IntergrationMenu menu : list) {
            if (menu.getId().equals(item.getParentId())) {
                result.add(menu);
                if (menu.getParentId() != null) {
                    result.addAll(findParentMenus(list, menu));
                }
                return result;
            }
        }
        return result;
    }

    private List<IntergrationMenu> getRedisMenuByCode(String code) {
        UserInfo userInfo = redisLikeService.getUserInfoByCode(code);
        List<IntergrationMenu> menuList = redisServer.getData("IntergrationPlatformMenu", (key) -> dao.getAll());
        if (userInfo.getRoles().contains(1)) {
            return menuListByTree(menuList);
        }

        List<IntergrationMenu> passRule = new ArrayList<>();
        for (IntergrationMenu item : menuList) {
            if (item.getMetaPassRule()) {
                passRule.add(item);
                passRule.addAll(findParentMenus(menuList, item));
            }
        }

        Map<Integer, List<IntergrationPlatformRoleMenu>> roleMap = redisLikeService.getIntergrationRoleMenu();
        Set<Integer> menuId = new HashSet<>();

        userInfo.getRoles().forEach(item -> {
            List<IntergrationPlatformRoleMenu> roleMenuList = roleMap.get(item);
            if (roleMenuList != null) {
                roleMenuList.forEach(roleMenu -> {
                    menuId.add(roleMenu.getMenuId());
                });
            }
        });

        for (IntergrationMenu item : menuList) {
            if (menuId.contains(item.getId())) {
                passRule.add(item);
            }
        }
        passRule = passRule.stream().distinct().collect(Collectors.toList());
        return menuListByTree(passRule);
    }

    public ResultVo<String> updateMenuSettings(IntergrationMenu menuList) {
        if (menuList.getId() == null) {
            dao.insert(menuList);
            menuPushRedis();
            return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_NOTIFICATION, "插入成功。");
        } else {
            dao.updateById(menuList);
            menuPushRedis();
            return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_NOTIFICATION, "更新成功。");
        }
    }

    public ResultVo<String> deleteMenuSettings(Integer id) {
        LambdaQueryWrapper<IntergrationMenu> qw = new LambdaQueryWrapper<>();

        qw.eq(IntergrationMenu::getParentId, id);
        int count = dao.selectCount(qw);

        if (count > 0) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请先删除子节点。");
        }
        dao.deleteById(id);
        menuPushRedis();
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_NOTIFICATION, "删除成功。");
    }


}
