package com.fzm.mall.server.admin.auth_center.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzm.mall.server.admin.auth_center.entity.vo.AuthMenuVO;
import com.fzm.mall.server.admin.auth_center.entity.vo.RoleAuthMenuVO;
import com.fzm.mall.server.admin.auth_center.enums.status.AuthStatusEnum;
import com.fzm.mall.server.admin.auth_center.enums.type.AdminRoleTypeEnum;
import com.fzm.mall.server.admin.auth_center.mapper.AuthMenuMapper;
import com.fzm.mall.server.admin.auth_center.model.AdminRole;
import com.fzm.mall.server.admin.auth_center.model.AuthMenu;
import com.fzm.mall.server.admin.auth_center.service.IAdminRoleService;
import com.fzm.mall.server.admin.auth_center.service.IAuthMenuService;
import com.fzm.mall.server.admin.constant.MALLGlobalConfig;
import com.fzm.mall.server.admin.home_page.enums.type.AdminTypeEnum;
import com.fzm.mall.server.admin.home_page.model.Admin;
import com.fzm.mall.server.admin.home_page.service.IAdminService;
import lombok.RequiredArgsConstructor;
import org.dozer.DozerBeanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @author wangp
 * @date 2021/4/8 13:41
 * @description 管理员权限 服务实现类
 * @since JDK 1.8
 */
@Service
@Transactional
public class AuthMenuServiceImpl extends ServiceImpl<AuthMenuMapper, AuthMenu> implements IAuthMenuService {

    @Autowired
    private DozerBeanMapper beanMapper;
    @Autowired
    private IAdminService adminService;
    @Autowired
    private IAdminRoleService adminRoleService;

    @Override
    public List<RoleAuthMenuVO> getRoleAuthMenu(Integer type, String roleId) {
        //默认权限菜单索引
        List<Integer> indexs = null;
        switch (AdminRoleTypeEnum.getByType(type)) {
            case PLATFORM:
                Integer[] PLATFORM_DEFAULT_AUTH = {
                        1101, 1103, 1104, 1102, 1105, 1006,
                        1001, 1007, 1008, 2001, 2002, 2003,
                        2004, 5001, 5013, 5008, 5007, 5002,
                        5014, 5009, 5006, 3010, 3009, 3011,
                        3013, 3012, 3005, 1301, 1304, 1302,
                        1303, 8001, 8002, 1201, 1203, 1202,
                        9001, 9002
                };
                indexs = Arrays.asList(PLATFORM_DEFAULT_AUTH);
                break;
            case PLATFORM_MERCHANT:
                Integer[] PLATFORM_MERCHANT_DEFAULT_AUTH = {
                        1001, 1002, 1005, 1009, 1008, 1003,
                        1004, 2001, 2002, 3004, 3002, 3001,
                        5001, 5002, 5003, 5006, 7002, 7001,
                        7003, 7004, 4001, 4002, 8001, 8002,
                        1201, 9001, 9002
                };

                indexs = Arrays.asList(PLATFORM_MERCHANT_DEFAULT_AUTH);
                break;
            case MERCHANT:
                Integer[] MERCHANT_DEFAULT_AUTH = {
                        1001, 1002, 1005, 1009, 1008, 2001,
                        2002, 3004, 3002, 3001, 5001, 5002,
                        5003, 5006, 7002, 7001, 7003, 7004,
                        4001, 4002, 8001, 8002, 1201, 9001,
                        9002
                };
                indexs = Arrays.asList(MERCHANT_DEFAULT_AUTH);
                break;
        }

        //权限菜单
        QueryWrapper<AuthMenu> qw = new QueryWrapper<>();
        qw.lambda().eq(AuthMenu::getStatus, AuthStatusEnum.NORMAL.getStatus())
                .in(AuthMenu::getMenuIndex, indexs);
        List<AuthMenu> authMenus = list(qw);

        List<RoleAuthMenuVO> wrapper;
        if (roleId != null) {
            wrapper = getSelfDefineAuthMenuWrapper(authMenus, roleId);
        } else {
            wrapper = getDefaultAuthMenuWrapper(authMenus);
        }

        return wrapper;
    }

    @Override
    public List<RoleAuthMenuVO> getAllAuthMenu() {
        //权限菜单
        QueryWrapper<AuthMenu> qw = new QueryWrapper<>();
        qw.lambda().eq(AuthMenu::getStatus, AuthStatusEnum.NORMAL.getStatus())
                .ne(AuthMenu::getParentMenuIndex, 0);
        List<AuthMenu> authMenus = list(qw);
        return getDefaultAuthMenuWrapper(authMenus);
    }

    List<RoleAuthMenuVO> getDefaultAuthMenuWrapper(List<AuthMenu> authMenus) {
        List<RoleAuthMenuVO> defaultAuthMenuWrapper = new ArrayList<>();

        //获取父权限菜单索引
        List<Integer> parentIndexs = authMenus.stream()
                .map(AuthMenu::getParentMenuIndex)
                .distinct()
                .collect(Collectors.toList());

        //权限包装
        parentIndexs.forEach(v -> {
            //父权限
            RoleAuthMenuVO parentAuth = getIndex(v);
            //子权限
            List<RoleAuthMenuVO> subAuth = new ArrayList<>();
            authMenus.stream()
                    .filter(f -> f.getParentMenuIndex().equals(v))
                    .forEach(m -> subAuth.add(beanMapper.map(m, RoleAuthMenuVO.class)));
            parentAuth.setSubAuthMenu(subAuth);
            defaultAuthMenuWrapper.add(parentAuth);
        });

        //根权限
        List<RoleAuthMenuVO> voList = new ArrayList<>();
        RoleAuthMenuVO vo = new RoleAuthMenuVO();
        vo.setMenuName("全部权限");
        vo.setMenuIndex(0000);
        vo.setSelect(false);
        vo.setSubAuthMenu(defaultAuthMenuWrapper);
        voList.add(vo);

        return voList;
    }

    List<RoleAuthMenuVO> getSelfDefineAuthMenuWrapper(List<AuthMenu> authMenus, String roleId) {
        List<RoleAuthMenuVO> selfDefineAuthMenuWrapper = new ArrayList<>();

        //获取父权限菜单索引
        List<Integer> parentIndexs = authMenus.stream()
                .map(AuthMenu::getParentMenuIndex)
                .distinct()
                .collect(Collectors.toList());

        //角色权限
        String authJson = adminRoleService.getByRoleIdIsNotDel(roleId).getAuthJson();
        List<Integer> auths = JSONArray.parseArray(authJson, Integer.class);

        //权限包装
        parentIndexs.forEach(v -> {
            //父权限
            RoleAuthMenuVO parentAuth = getIndex(v);

            //子权限
            List<RoleAuthMenuVO> subAuth = new ArrayList<>();
            authMenus.stream()
                    .filter(f -> f.getParentMenuIndex().equals(v))
                    .forEach(m -> {
                        RoleAuthMenuVO subAuthWrapper = beanMapper.map(m, RoleAuthMenuVO.class);
                        long count = auths.stream().filter(t -> subAuthWrapper.getMenuIndex().equals(t)).count();
                        subAuthWrapper.setSelect(count == 1);
                        subAuth.add(subAuthWrapper);
                    });
            parentAuth.setSubAuthMenu(subAuth);

            //父权限
            boolean parentSelect = false;
            for (RoleAuthMenuVO sub : subAuth) {
                parentSelect = sub.getSelect();
                if (!parentSelect) break;
            }
            parentAuth.setSelect(parentSelect);
            selfDefineAuthMenuWrapper.add(parentAuth);
        });

        //根权限
        List<RoleAuthMenuVO> voList = new ArrayList<>();
        RoleAuthMenuVO vo = new RoleAuthMenuVO();
        vo.setMenuName("全部权限");
        vo.setMenuIndex(0000);
        vo.setSubAuthMenu(selfDefineAuthMenuWrapper);

        boolean rootSelect = false;
        for (RoleAuthMenuVO sub : selfDefineAuthMenuWrapper) {
            rootSelect = sub.getSelect();
            if (!rootSelect) break;
        }
        vo.setSelect(rootSelect);
        voList.add(vo);

        return voList;
    }

    public RoleAuthMenuVO getIndex(Integer index) {
        QueryWrapper<AuthMenu> qw = new QueryWrapper<>();
        qw.lambda()
                .eq(AuthMenu::getStatus, AuthStatusEnum.NORMAL.getStatus())
                .eq(AuthMenu::getMenuIndex, index);
        return beanMapper.map(getOne(qw), RoleAuthMenuVO.class);
    }

    //============================================旧版=================================================

    @Override
    public List<AuthMenuVO> getPlatFormDefaultAuthMenu() {
        //平台默认权限菜单索引
        List<Integer> indexs = Arrays.asList(MALLGlobalConfig.PLAT_DEFAULT_AUTH);

        //权限菜单
        QueryWrapper<AuthMenu> qw = new QueryWrapper<>();
        qw.lambda().eq(AuthMenu::getStatus, AuthStatusEnum.NORMAL.getStatus())
                .in(AuthMenu::getMenuIndex, indexs);
        List<AuthMenu> authMenus = list(qw);

        return getAuthMenuWrapper(authMenus);
    }

    @Override
    public List<AuthMenu> getAdminAuthMenu(String adminId) {
        Admin admin = adminService.getByAdminId(adminId);
        if (admin == null)
            return new ArrayList<>();
        String roleId = admin.getRoleId();
        AdminRole adminRole = adminRoleService.getByRoleId(roleId);
        if (adminRole == null)
            return new ArrayList<>();
        String authJson = adminRole.getAuthJson();

        List<Integer> indexs = JSONArray.parseArray(authJson, Integer.class);

        List<AuthMenu> authMenus = indexs.stream()
                .map(this::getInnerByIndex)
                .collect(Collectors.toList());

        return authMenus;
    }

    @Override
    public List<AuthMenuVO> getAdminAuthMenuVO(String adminId) {
        List<AuthMenu> adminAuthMenu = getAdminAuthMenu(adminId);
        return getAuthMenuWrapper(adminAuthMenu);
    }

    List<AuthMenuVO> getAuthMenuWrapper(List<AuthMenu> authMenus) {
        //获取父权限菜单
        List<Integer> parentIndexs = authMenus.stream()
                .map(AuthMenu::getParentMenuIndex)
                .distinct()
                .collect(Collectors.toList());

        //权限包装
        List<AuthMenuVO> authMenuWrapperVOS = parentIndexs.stream()
                .map(this::getByIndex)
                .peek(p -> {
                    List<AuthMenuVO> authMenuVOS = authMenus.stream()
                            .filter(f -> f.getParentMenuIndex().equals(p.getMenuIndex()))
                            .map(m -> beanMapper.map(m, AuthMenuVO.class))
                            .collect(Collectors.toList());
                    p.setSubAuthMenu(authMenuVOS);
                })
                .collect(Collectors.toList());

        return authMenuWrapperVOS;
    }

    public AuthMenuVO getByIndex(Integer index) {
        QueryWrapper<AuthMenu> qw = new QueryWrapper<>();
        qw.lambda()
                .eq(AuthMenu::getStatus, AuthStatusEnum.NORMAL.getStatus())
                .eq(AuthMenu::getMenuIndex, index);
        return beanMapper.map(getOne(qw), AuthMenuVO.class);
    }

    public AuthMenu getInnerByIndex(Integer index) {
        QueryWrapper<AuthMenu> qw = new QueryWrapper<>();
        qw.lambda()
                .eq(AuthMenu::getStatus, AuthStatusEnum.NORMAL.getStatus())
                .eq(AuthMenu::getMenuIndex, index);
        return getOne(qw);
    }
}
