package com.ssm.manage.service.impl;

import com.ssm.core.service.impl.BaseServiceImpl;
import com.ssm.core.utils.SnowflakeUtil;
import com.ssm.manage.dao.RlRoleStaffDao;
import com.ssm.manage.dao.SsmSysMenuPowerDao;
import com.ssm.manage.dao.SsmSysMuenRoleDao;
import com.ssm.manage.entity.*;
import com.ssm.manage.query.MenuPowerRequest;
import com.ssm.manage.query.MenuRequest;
import com.ssm.manage.query.PowerRequest;
import com.ssm.manage.response.ResponseCode;
import com.ssm.manage.response.SysMenuResponse;
import com.ssm.manage.service.SsmSysMenuPowerService;
import com.ssm.manage.service.SsmSysPowerService;
import com.ssm.manage.service.SsmSysRolePowerService;
import io.swagger.models.auth.In;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.IdGenerator;
import tk.mybatis.mapper.entity.Example;

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

@Service
public class SsmSysMenuPowerServiceImpl extends BaseServiceImpl<SysMenuPower> implements SsmSysMenuPowerService {

    @Autowired
    private SsmSysRolePowerService ssmSysRolePowerService;

    @Autowired
    private SsmSysMenuPowerDao dao;

    @Autowired
    private RlRoleStaffDao rlRoleStaffDao;

    @Autowired
    private SsmSysMuenRoleDao ssmSysMuenRoleDao;

    @Autowired
    private SsmSysPowerService ssmSysPowerService;


    @Override
    public SsmSysMenuPowerDao getDao() {
        return dao;
    }

//    @Override
//    public int saveMenuPower(MenuPowerRequest menuPowerRequest) {
//        return dao.saveMenuPower(menuPowerRequest);
//    }
//
    @Override
    public List<SysMenuPower> listMenuPower(MenuPowerRequest menuPowerRequest) {
        List<SysMenuPower> list =  dao.selectAll();
        return getList(list);
    }

    @Override
    public List<SysMenuPower> listNew(MenuPowerRequest menuPowerRequest) {
        List<SysMenuPower> list =  dao.selectAll();
        return getListByTree(list);
    }

    @Override
    public List<SysMenuPower> listbyStaffId(MenuPowerRequest menuPowerRequest) {
        RlRoleStaff rlRoleStaff = new RlRoleStaff();
        rlRoleStaff.setStaffId(menuPowerRequest.getStaffId());
        List<RlRoleStaff> select = rlRoleStaffDao.select(rlRoleStaff);
        List<Long> roleIds = select.stream().map(RlRoleStaff::getRoleId).collect(Collectors.toList());
        //查询这些角色的所拥有的权限
        Example example = new Example(SysMuenRole.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("roleId",roleIds);
        List<SysMuenRole> sysMuenRoles = ssmSysMuenRoleDao.selectByExample(example);
        List<Integer> powerId = sysMuenRoles.stream().map(item -> item.getPowerId()).distinct().collect(Collectors.toList());
        Example example1 = new Example(SysMenuPower.class);
        Example.Criteria criteria1 = example1.createCriteria();
        criteria1.andIn("id",powerId);
        Example.Criteria criteria2 = example1.createCriteria();
        criteria2.orIsNull("parentId");
        example1.or(criteria2);
        List<SysMenuPower> list =  dao.selectByExample(example1);
        return getList(list);
    }
    @Override
    public List<SysMenuPower> selectAll(MenuPowerRequest menuPowerRequest) {
        SysMenuPower sysMenuPower = new SysMenuPower();
        sysMenuPower.setType(0);
        List<SysMenuPower> list =  dao.select(sysMenuPower);

        return getAllMenuList(list);
    }

    @Override
    public List<SysMenuPower> listByRole(MenuPowerRequest menuPowerRequest) {
        //查询角色权限表
        Example rolePowerExample = new Example(SysRolePower.class);
        if (menuPowerRequest.getRoleId() != null) {
            rolePowerExample.createCriteria().andEqualTo("roleId", menuPowerRequest.getRoleId());
        }
        List<SysRolePower> rolePowerList = ssmSysRolePowerService.selectByExample(rolePowerExample);
        List<SysMenuPower> list = new ArrayList<>();
        if(rolePowerList.size() > 0) {
            //将权限ID提取出来
            List<Integer> powerIds = new ArrayList<>(rolePowerList.size());
            for (SysRolePower sysRolePower : rolePowerList) {
                powerIds.add(sysRolePower.getPowerId());
            }
            //查询权限表
            Example powerExample = new Example(SysMenuPower.class);
            if (powerIds.size() > 0) {
                powerExample.createCriteria().andIn("id", powerIds);
            }
            list = dao.selectByExample(powerExample);
            return getList(list);
        }
        return list;
    }

    @Override
    @Transactional
    public void addMenuPower(PowerRequest menuPowerRequest) {
        SysMenuPower menuPower = menuPowerRequest.getMenuPower();
        SysPower sysPower = new SysPower();
        BeanUtils.copyProperties(menuPowerRequest,sysPower);
        sysPower.setPowerId(menuPowerRequest.getPowerId().toString());
        ssmSysPowerService.save(sysPower);
        menuPower.setId(Integer.valueOf(sysPower.getPowerId()));
        dao.insert(menuPower);
        //给当前用户增加权限
        RlRoleStaff rlRoleStaff = new RlRoleStaff();
        rlRoleStaff.setStaffId(menuPowerRequest.getStaffId());
        List<RlRoleStaff> select = rlRoleStaffDao.select(rlRoleStaff);
        for (RlRoleStaff roleStaff : select) {
            SysMuenRole sysMuenRole = new SysMuenRole();
            sysMuenRole.setRoleId(roleStaff.getRoleId());
            sysMuenRole.setPowerId(Integer.valueOf(sysPower.getPowerId()));
            ssmSysMuenRoleDao.insert(sysMuenRole);
        }
    }

    @Override
    @Transactional
    public void delete(PowerRequest menuPowerRequest) throws SmsException {
        SysMenuPower sysMenuPower = new SysMenuPower();
        sysMenuPower.setParentId(menuPowerRequest.getPowerId().toString());
        List<SysMenuPower> sysMenuPowerList = dao.select(sysMenuPower);
        if(sysMenuPowerList!=null && sysMenuPowerList.size()>0){
            throw new SmsException(ResponseCode.MSG,"存在子菜单或者子权限，不允许删除");
        }

        ssmSysPowerService.deleteByPowerId(menuPowerRequest.getPowerId());
        dao.deleteByPrimaryKey(menuPowerRequest.getPowerId());
    }


    @Override
    @Transactional
    public void update(PowerRequest menuPowerRequest) {
        SysMenuPower menuPower = menuPowerRequest.getMenuPower();
        SysPower sysPower = new SysPower();
        BeanUtils.copyProperties(menuPowerRequest,sysPower);
        sysPower.setPowerId(menuPowerRequest.getPowerId().toString());
        ssmSysPowerService.updateNotNull(sysPower);
        menuPower.setId(Integer.valueOf(sysPower.getPowerId()));
        dao.updateByPrimaryKeySelective(menuPower);
    }

    public List getList(List<SysMenuPower> list){
        List resultList = new ArrayList();
        MenuPowerRequest menuPowerRequest = null;
        List<PowerRequest> checkList = null;
        List<MenuRequest> menuList = null;
        Map<Integer,MenuPowerRequest> tempMap = new HashMap();
        Map<Integer,MenuRequest> menuMap = new HashMap();
//        Map<Integer,MenuPowerRequest> powerMap = new HashMap();
        for (SysMenuPower sysMenuPower : list){
            //菜单
            if (sysMenuPower.getType() == 0) {
                //一级菜单
                if (sysMenuPower.getParentId() == null || sysMenuPower.getParentId().equals("")){
                    menuList = new ArrayList<>();
                    menuPowerRequest = new MenuPowerRequest();
                    menuPowerRequest.setId(sysMenuPower.getId());//菜单ID
                    menuPowerRequest.setPowerName(sysMenuPower.getPowerName());//菜单名称
                    menuPowerRequest.setMenuList(menuList);
                    menuPowerRequest.setType(0);
                    menuPowerRequest.setState(Integer.valueOf(sysMenuPower.getState()));
                    tempMap.put(sysMenuPower.getId(), menuPowerRequest);
                }else {
                    //二级菜单  后面进来 直接使用tempMap中的实体
                    menuPowerRequest = (MenuPowerRequest) tempMap.get(Integer.valueOf(sysMenuPower.getParentId()));
                    if(null != menuPowerRequest){
                        menuList = menuPowerRequest.getMenuList();
                    }

                    checkList = new ArrayList<>();
                    MenuRequest menuRequest = new MenuRequest();
                    menuRequest.setMenuId(sysMenuPower.getId());//菜单ID
                    menuRequest.setMenuName(sysMenuPower.getPowerName());//菜单名称
                    menuList.add(menuRequest);
                    menuRequest.setCheckList(checkList);
                    menuRequest.setType(0);
                    menuRequest.setState(Integer.valueOf(sysMenuPower.getState()));
                    menuMap.put(sysMenuPower.getId(),menuRequest);
                }
            }else {
                //后面进来 直接使用tempMap中的实体 添加权限List
                MenuRequest menuRequest = menuMap.get(Integer.valueOf(sysMenuPower.getParentId()));
                if (menuRequest.getMenuId().intValue() == Integer.valueOf(sysMenuPower.getParentId()).intValue()) {
                    checkList = menuRequest.getCheckList();
                    PowerRequest powerRequest = new PowerRequest();
                    powerRequest.setPowerId(sysMenuPower.getId());
                    powerRequest.setPowerName(sysMenuPower.getPowerName());
                    powerRequest.setType(0);
                    powerRequest.setState(Integer.valueOf(sysMenuPower.getState()));
                    checkList.add(powerRequest);
                }

//                menuPowerRequest.setCheckList(checkList);
            }
        }
        //遍历tempMap 放入返回list中
        for (Map.Entry<Integer, MenuPowerRequest> stringMenuPowerRequestEntry : tempMap.entrySet()) {
            MenuPowerRequest mp = stringMenuPowerRequestEntry.getValue();
            resultList.add(mp);
        }
        return resultList;
    }

    public List getAllMenuList(List<SysMenuPower> list){
        List resultList = new ArrayList();
        MenuPowerRequest menuPowerRequest = null;
        List<PowerRequest> checkList = null;
        List<MenuRequest> menuList = null;
        Map<Integer,MenuPowerRequest> tempMap = new HashMap();
        Map<Integer,MenuRequest> menuMap = new HashMap();
//        Map<Integer,MenuPowerRequest> powerMap = new HashMap();
        for (SysMenuPower sysMenuPower : list){
            //菜单
            if (sysMenuPower.getType() == 0) {
                //一级菜单
                if (sysMenuPower.getParentId() == null || sysMenuPower.getParentId().equals("")){
                    menuList = new ArrayList<>();
                    menuPowerRequest = new MenuPowerRequest();
                    menuPowerRequest.setId(sysMenuPower.getId());//菜单ID
                    menuPowerRequest.setPowerName(sysMenuPower.getPowerName());//菜单名称
                    menuPowerRequest.setType(0);
                    menuPowerRequest.setState(Integer.valueOf(sysMenuPower.getState()));
                    menuPowerRequest.setMenuList(menuList);

                    tempMap.put(sysMenuPower.getId(), menuPowerRequest);
                }else {
                    //二级菜单  后面进来 直接使用tempMap中的实体
                    menuPowerRequest = (MenuPowerRequest) tempMap.get(Integer.valueOf(sysMenuPower.getParentId()));
                    if(null != menuPowerRequest){
                        menuList = menuPowerRequest.getMenuList();
                    }

                    checkList = new ArrayList<>();
                    MenuRequest menuRequest = new MenuRequest();
                    menuRequest.setMenuId(sysMenuPower.getId());//菜单ID
                    menuRequest.setMenuName(sysMenuPower.getPowerName());//菜单名称
                    menuList.add(menuRequest);
                    menuRequest.setCheckList(checkList);
                    menuRequest.setType(0);
                    menuRequest.setState(Integer.valueOf(sysMenuPower.getState()));
                    menuMap.put(sysMenuPower.getId(),menuRequest);
                }
            }
        }
        //遍历tempMap 放入返回list中
        for (Map.Entry<Integer, MenuPowerRequest> stringMenuPowerRequestEntry : tempMap.entrySet()) {
            MenuPowerRequest mp = stringMenuPowerRequestEntry.getValue();
            resultList.add(mp);
        }
        return resultList;
    }

    public List getListByTree(List<SysMenuPower> list){
//        List resultList = new ArrayList();
        //一级菜单
        List<SysMenuResponse> zeroMenu = new ArrayList<>();
        for (SysMenuPower sysMenuPower : list) {
            if(sysMenuPower.getParentId()==null || sysMenuPower.getParentId().equals("")){
                SysMenuResponse sysMenuResponse = new SysMenuResponse();
                BeanUtils.copyProperties(sysMenuPower,sysMenuResponse);
                zeroMenu.add(sysMenuResponse);
            }
        }
        for (SysMenuResponse menu : zeroMenu) {
            menu.setMenuList(getChildren(menu.getId(),list));
        }
        return zeroMenu;
    }

    public List<SysMenuResponse> getChildren(Integer id,List<SysMenuPower> list){
        List<SysMenuResponse> children = new ArrayList<>();
        for (SysMenuPower sysMenuPower : list) {
            if((sysMenuPower.getParentId()!=null && !sysMenuPower.getParentId().equals("")) && (Integer.valueOf(sysMenuPower.getParentId())==id || sysMenuPower.getParentId().equals(id.toString()))){
                SysMenuResponse sysMenuResponse = new SysMenuResponse();
                BeanUtils.copyProperties(sysMenuPower,sysMenuResponse);
                sysMenuResponse.setParentId(id);
                sysMenuResponse.setMenuList(getChildren(sysMenuPower.getId(),list));
                children.add(sysMenuResponse);
            }
        }
        return children;
    }

}
