package com.czg.service.account.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.czg.account.dto.menu.MenuAddDTO;
import com.czg.account.dto.menu.MenuEditDTO;
import com.czg.account.entity.CashMenu;
import com.czg.account.entity.SysMenu;
import com.czg.account.service.CashMenuService;
import com.czg.account.service.ShopInfoService;
import com.czg.account.service.SysMenuService;
import com.czg.account.vo.MenuVO;
import com.czg.exception.CzgException;
import com.czg.sa.StpKit;
import com.czg.service.account.mapper.SysMenuMapper;
import com.czg.service.account.mapper.SysUsersRolesMapper;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统菜单 服务层实现。
 *
 * @author Administrator
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Resource
    private SysMenuMapper sysMenuMapper;
    @Resource
    private SysUsersRolesMapper sysUsersRolesMapper;
    @Resource
    private CashMenuService cashMenuService;
    @Resource
    private ShopInfoService shopInfoService;

    @Override
    public List<MenuVO> getMenu() {
        long sysUserId = StpKit.USER.getLoginIdAsLong();
        List<SysMenu> allMenus = mapper.selectByUserId(sysUserId, "PC".equals(StpKit.USER.getPlatForm()) ? 1 : 0);
//        SysUsersRoles usersRoles = sysUsersRolesMapper.selectOneByQuery(query().select(SysUsersRoles::getRoleId).eq(SysUsersRoles::getUserId, sysUserId));
//        Long shopId = StpKit.USER.getShopId(0L);
//        Long mainShopId = shopInfoService.getMainIdByShopId(shopId);
//        boolean isEnableSync = mainShopId.equals(shopId);
//        if (isEnableSync && roleIdList.contains(2L)) {
//            List<SysMenu> headShopPromissionList = sysMenuMapper.selectByRoleId(2L);
//            List<SysMenu> branchShopPromissionList = sysMenuMapper.selectByRoleId(3L);
//            allMenus.removeAll(headShopPromissionList);
//            allMenus.addAll(branchShopPromissionList);
//        }

        List<MenuVO> menuVos = allMenus.stream()
                .distinct()
                .map(menu -> BeanUtil.copyProperties(menu, MenuVO.class))
                .collect(Collectors.toList());
        return buildMenuWithPermissions(menuVos);
    }

    @Override
    public List<MenuVO> getAll(String title, String startTime, String endTime) {
        QueryWrapper queryWrapper = new QueryWrapper();
        if (StrUtil.isNotBlank(title)) {
            queryWrapper.like(SysMenu::getTitle, title);
        }

        if (StrUtil.isNotBlank(startTime)) {
            queryWrapper.ge(SysMenu::getCreateTime, DateUtil.parse(startTime));
        }

        if (StrUtil.isNotBlank(endTime)) {
            queryWrapper.le(SysMenu::getCreateTime, DateUtil.parse(endTime));
        }

        List<SysMenu> allMenus;
        if (queryWrapper.hasCondition()) {
            allMenus = list(queryWrapper.orderBy(SysMenu::getMenuSort, false));
            return allMenus.stream()
                    .map(item -> BeanUtil.copyProperties(item, MenuVO.class))
                    .collect(Collectors.toList());
        } else {
            allMenus = list(new QueryWrapper().orderBy(SysMenu::getMenuSort, false));
            return buildMenuTree(allMenus);
        }
    }

    @Override
    public Boolean add(MenuAddDTO menuAddDTO) {
        checkExIsis(menuAddDTO.getTitle(), null);
        if (menuAddDTO.getType() == 2 && menuAddDTO.getPid() == null) {
            throw new CzgException("二级菜单必须传递父id");
        }

        if (menuAddDTO.getType() == 3 && menuAddDTO.getPid() == null) {
            throw new CzgException("父id不为空");
        }

        if (menuAddDTO.getType() == 3 && menuAddDTO.getPermission() == null) {
            throw new CzgException("权限不为空");
        }
        SysMenu sysMenu = BeanUtil.copyProperties(menuAddDTO, SysMenu.class);
        if (menuAddDTO.getApiInfo() != null && !menuAddDTO.getApiInfo().isEmpty()) {
            sysMenu.setApiInfo(JSONObject.toJSONString(menuAddDTO.getApiInfo()));
        }
        return save(sysMenu);
    }

    @Override
    public Boolean edit(MenuEditDTO menuEditDTO) {
        checkExIsis(menuEditDTO.getTitle(), menuEditDTO.getId());
        SysMenu menu = getById(menuEditDTO.getId());
        if (menu == null) {
            throw new CzgException("菜单不存在");
        }
        BeanUtil.copyProperties(menuEditDTO, menu);
        if (menuEditDTO.getApiInfo() != null && !menuEditDTO.getApiInfo().isEmpty()) {
            menu.setApiInfo(JSONObject.toJSONString(menuEditDTO.getApiInfo()));
        }
        if (menuEditDTO.getPid() == null) {
            menu.setPid(null);
        }
        return updateById(menu, false);
    }


    private void checkExIsis(String title, Integer id) {
//        QueryWrapper queryWrapper = new QueryWrapper();
//        if (id != null) {
//            queryWrapper.ne(SysMenu::getMenuId, id);
//        }
//        queryWrapper.eq(SysMenu::getTitle, title);
//        long count = count(queryWrapper);
//        if (count > 0) {
//            throw new CzgException("名称已存在");
//        }
    }

    private List<MenuVO> buildMenuTree(List<SysMenu> allMenus) {
        List<MenuVO> menuVos = allMenus.stream()
                .map(menu -> BeanUtil.copyProperties(menu, MenuVO.class))
                .collect(Collectors.toList());
        return buildSubMenus(null, menuVos, false);
    }

    private List<MenuVO> buildMenuWithPermissions(List<MenuVO> allMenus) {
        return buildSubMenus(null, allMenus, true);
    }

    private List<MenuVO> buildSubMenus(Long parentId, List<MenuVO> allMenus, boolean includePermissions) {
        List<MenuVO> resultMenus = new ArrayList<>();
        for (MenuVO menu : allMenus) {
            if ((menu.getPid() == null && parentId == null) || (menu.getPid() != null && menu.getPid().equals(parentId))) {
                List<String> permissions = new ArrayList<>();
                List<MenuVO> children = buildSubMenus(menu.getMenuId(), allMenus, includePermissions);

                if (includePermissions) {
                    for (MenuVO child : new ArrayList<>(children)) {
                        if (child.getType() == 2) {
                            permissions.addAll(getPermissionsForMenu(child));
                            children.remove(child);
                        }
                    }
                }

                menu.setChildren(children);
                if (includePermissions) {
                    menu.setPermissions(permissions);
                }
                resultMenus.add(menu);
            }
        }
        return resultMenus;
    }

    private List<String> getPermissionsForMenu(MenuVO menu) {
        List<String> permissions = new ArrayList<>();
        if (menu.getPermission() != null) {
            permissions.addAll(Arrays.asList(menu.getPermission().split(",")));
        }
        return permissions;
    }

    @Override
    public List<CashMenu> getCashAll() {
        return cashMenuService.list();
    }
}
