package com.ym.mec.biz.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.EmployeeDao;
import com.ym.mec.biz.dal.dao.PlatformProductDao;
import com.ym.mec.biz.dal.dto.PlatformProductDto;
import com.ym.mec.biz.dal.entity.PlatformProduct;
import com.ym.mec.biz.service.PlatformProductService;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.page.PageUtil;
import com.ym.mec.common.page.WrapperUtil;
import org.apache.commons.collections.CollectionUtils;
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;

/**
 * @author hgw
 * Created by 2021-12-02
 */
@Service
public class PlatformProductServiceImpl extends ServiceImpl<PlatformProductDao, PlatformProduct> implements PlatformProductService {
    @Autowired
    private SysUserFeignService sysUserFeignService;
    @Autowired
    private EmployeeDao employeeDao;

    /**
     * 增加
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addProduct(PlatformProductDto obj) {
        Integer userId = Optional.ofNullable(sysUserFeignService.queryUserInfo())
                .map(SysUser::getId)
                .orElseThrow(() -> new BizException("用户信息获取失败"));

        PlatformProduct platformProduct = new PlatformProduct();
        platformProduct.setName(obj.getName());
        platformProduct.setMenuId(obj.getMenuId());
        platformProduct.setRemark(obj.getRemark());
        platformProduct.setDeleted(0);
        platformProduct.setCreatedBy(userId);
        platformProduct.setCreatedTime(new Date());
        baseMapper.insert(platformProduct);
    }

    /**
     * 修改
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateProduct(PlatformProductDto dto) {
        Optional.ofNullable(dto.getId()).orElseThrow(() -> new BizException("产品Id不能为空"));
        Integer userId = Optional.ofNullable(sysUserFeignService.queryUserInfo())
                .map(SysUser::getId)
                .orElseThrow(() -> new BizException("用户信息获取失败"));
        //查询该产品
        PlatformProduct sourceObj = Optional.ofNullable(this.getById(dto.getId()))
                .filter(s -> s.getDeleted() == 0)
                .orElseThrow(() -> new BizException("未查询到该产品信息!"));

        PlatformProduct platformProduct = new PlatformProduct();
        platformProduct.setId(dto.getId());
        platformProduct.setName(dto.getName());
        platformProduct.setMenuId(dto.getMenuId());
        platformProduct.setRemark(dto.getRemark());
        platformProduct.setUpdatedBy(userId);
        platformProduct.setUpdatedTime(new Date());
        baseMapper.updateByPrimaryKeySelective(platformProduct);
        //查询该产品有多少机构关联
        Map<Integer, Integer> map = queryTenantByMultiId(dto.getId(), null, null);
        //检查是否需要修改权限
        checkUpdateRole(dto.getMenuId(), sourceObj.getMenuId(), map);
    }

    /**
     * 检查哪些机构用了这个产品，需要修改对应的权限
     *
     * @param newMenuIds 修改后的的菜单id，用逗号隔开
     * @param oldMenuIds 修改之前的的菜单id，用逗号隔开
     * @param map        Map<机构id，机构的管理员id> queryProductInTenant
     */
    @Transactional(rollbackFor = Exception.class)
    public void checkUpdateRole(String newMenuIds, String oldMenuIds, Map<Integer, Integer> map) {
        //需要添加的菜单id
        List<Integer> newList = WrapperUtil.splitToIntList(newMenuIds);
        //需要删除的菜单id
        List<Integer> oldList = WrapperUtil.splitToIntList(oldMenuIds);
        //合并修改权限
        opsRoleMenu(map, newList, oldList);
    }

    private void opsRoleMenu(Map<Integer, Integer> map, List<Integer> newList, List<Integer> oldList) {
        if (Objects.isNull(map)) {
            return;
        }
        //求新旧产品菜单的差异
        WrapperUtil.listDifference(oldList, newList);
        //修改数据
        map.forEach((tenantId, uId) -> {
            if (CollectionUtils.isNotEmpty(newList)) {
                //uId查询机构管理员角色
                List<Integer> roles = employeeDao.queryUserRole(uId);
                //机构管理员只会有一个管理员角色
                Integer adminRole = roles.get(0);
                //给管理员角色添加dtoList菜单id
                Lists.partition(newList, 50)
                        .forEach(idList -> baseMapper.batchInsertRoleMenu(adminRole, idList, tenantId));
            }
            //根据机构id 和 角色的菜单id删除信息
            if (CollectionUtils.isNotEmpty(oldList)) {
                Lists.partition(oldList, 50)
                        .forEach(idList -> employeeDao.delRoleMenu(tenantId, idList));
            }
        });
    }

    /**
     * 根据多个id 查询出机构的id 和机构管理员id
     *
     * @param productId 产品id
     * @param serveId   服务id
     * @param tenantId  机构id
     */
    public Map<Integer, Integer> queryTenantByMultiId(Integer productId, Integer serveId, Integer tenantId) {
        List<Map<Integer, Integer>> mapList = baseMapper.queryTenantByMultiId(productId, serveId, tenantId);
        if (CollectionUtils.isEmpty(mapList)) {
            return null;
        }
        //Map<机构id,机构的管理员id>
        return mapList.stream()
                .collect(Collectors.toMap(m -> m.get("tenantId"), m -> m.get("userId"), (a, b) -> b));
    }

    /**
     * 删除
     *
     * @param id 产品id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteProduct(Integer id) {
        Optional.ofNullable(id).orElseThrow(() -> new BizException("产品Id不能为空"));
        Integer userId = Optional.ofNullable(sysUserFeignService.queryUserInfo())
                .map(SysUser::getId)
                .orElseThrow(() -> new BizException("用户信息获取失败"));
        //校验哪些机构用了该产品
        List<Map<Integer, Integer>> map = baseMapper.queryTenantByMultiId(id, null, null);
        if (CollectionUtils.isNotEmpty(map)) {
            throw new BizException("该产品关联的服务已有机构在使用，无法删除！");
        }

        PlatformProduct platformProduct = new PlatformProduct();
        platformProduct.setId(id);
        platformProduct.setDeleted(1);
        platformProduct.setUpdatedBy(userId);
        platformProduct.setUpdatedTime(new Date());
        baseMapper.updateByPrimaryKeySelective(platformProduct);
    }

    /**
     * 分页查询
     *
     * @param search 关键字
     * @param page   页数
     * @param rows   查询数
     */
    @Override
    public PageInfo<PlatformProduct> queryPage(String search, Integer page, Integer rows) {
        Page<PlatformProduct> pageInfo = PageUtil.getPage(page, rows);
        pageInfo.setAsc("id_");
        IPage<PlatformProduct> productIPage = baseMapper.queryPage(pageInfo, search);
        return PageUtil.pageInfo(productIPage);
    }

    /**
     * 根据serveId查询对应的菜单id集合
     *
     * @param serveId
     */
    @Override
    public List<String> queryMenuIdList(Integer serveId) {
        return baseMapper.queryMenuIdList(serveId);
    }

}
