package com.gic.haoban.manage.service.service.role.impl;

import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.clerk.api.dto.right.MenuDTO;
import com.gic.clerk.api.dto.right.MenuListQDTO;
import com.gic.clerk.api.service.MenuApiService;
import com.gic.commons.util.EntityUtil;
import com.gic.commons.util.UniqueIdUtils;
import com.gic.haoban.manage.service.dao.mapper.WxEnterpriseRelatedMapper;
import com.gic.haoban.manage.service.dao.mapper.role.TabHaobanMenuMapper;
import com.gic.haoban.manage.service.dao.mapper.role.TabHaobanRoleMapper;
import com.gic.haoban.manage.service.dao.mapper.role.TabHaobanRoleMenuMapper;
import com.gic.haoban.manage.service.entity.TabHaobanWxEnterpriseRelated;
import com.gic.haoban.manage.service.entity.role.TabHaobanMenu;
import com.gic.haoban.manage.service.entity.role.TabHaobanRole;
import com.gic.haoban.manage.service.entity.role.TabHaobanRoleMenu;
import com.gic.haoban.manage.service.pojo.bo.role.HaobanMenuBO;
import com.gic.haoban.manage.service.service.MemberQueryService;
import com.gic.haoban.manage.service.service.role.HaobanMenuService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author mozhu
 * @since 2022-09-06 16:35:11
 */
@Service
public class HaobanMenuServiceImpl implements HaobanMenuService {
    private static final Logger logger = LogManager.getLogger(HaobanMenuService.class);

    @Autowired
    private TabHaobanMenuMapper tabHaobanMenuMapper;
    @Autowired
    private WxEnterpriseRelatedMapper wxEnterpriseRelatedMapper ;
    @Autowired
    private TabHaobanRoleMapper roleMapper ;
    @Autowired
    private TabHaobanRoleMenuMapper roleMenuMapper ;
    @Autowired
    private MenuApiService menuApiService ;

    @Override
    public TabHaobanMenu queryById(String menuCode) {
        if (StringUtils.isBlank(menuCode)) {
            return null;
        }
        return this.tabHaobanMenuMapper.queryById(menuCode);
    }

    /**
     * 新增数据
     *
     * @param tabHaobanMenu 实例对象
     * @return 实例对象
     */
    @Override
    public int insert(TabHaobanMenu tabHaobanMenu) {
        tabHaobanMenu.setCreateTime(new Date());
        tabHaobanMenu.setUpdateTime(new Date());
        return this.tabHaobanMenuMapper.insert(tabHaobanMenu);
    }

    @Override
    public int insertBatch(List<TabHaobanMenu> tabHaobanMenus) {
        for (TabHaobanMenu tabHaobanMenu : tabHaobanMenus) {
            tabHaobanMenu.setStatusFlag(1);
            tabHaobanMenu.setCreateTime(new Date());
            tabHaobanMenu.setUpdateTime(new Date());
        }
        return tabHaobanMenuMapper.insertBatch(tabHaobanMenus);
    }

    /**
     * 修改数据
     *
     * @param tabHaobanMenu 实例对象
     * @return 实例对象
     */
    @Override
    public int update(TabHaobanMenu tabHaobanMenu) {
        tabHaobanMenu.setUpdateTime(new Date());
        return this.tabHaobanMenuMapper.update(tabHaobanMenu);
    }

    @Override
    public List<HaobanMenuBO> getAllMenuList() {
        List<TabHaobanMenu> allMenuList = tabHaobanMenuMapper.getAllMenuList();
        return EntityUtil.changeEntityListNew(HaobanMenuBO.class, allMenuList);
    }

    @Override
    public List<HaobanMenuBO> getMenuTreeList() {
        List<TabHaobanMenu> pidMenuList = tabHaobanMenuMapper.getPidMenuList();
        List<TabHaobanMenu> notPidMenuList = tabHaobanMenuMapper.getNotPidMenuList();
        List<HaobanMenuBO> pidMenuBOList = EntityUtil.changeEntityListNew(HaobanMenuBO.class, pidMenuList);
        List<HaobanMenuBO> notPidMenuBOList = EntityUtil.changeEntityListNew(HaobanMenuBO.class, notPidMenuList);
        for (HaobanMenuBO haobanMenuBO : pidMenuBOList) {
            List<HaobanMenuBO> menus = iterateMenus(notPidMenuBOList, haobanMenuBO.getMenuCode());
            haobanMenuBO.setMenuBOList(menus);
        }
        return pidMenuBOList;
    }

    @Override
    public List<HaobanMenuBO> getHaobanMenuTreeList(String wxEnterpriseId, Integer clerkType) {
        List<TabHaobanMenu> pidMenuList = tabHaobanMenuMapper.getHaobanPidMenuList(wxEnterpriseId, clerkType, 0);
        List<TabHaobanMenu> notPidMenuList = tabHaobanMenuMapper.getHaobanNotPidMenuList(wxEnterpriseId, clerkType, 0);
        List<HaobanMenuBO> pidMenuBOList = EntityUtil.changeEntityListNew(HaobanMenuBO.class, pidMenuList);
        List<HaobanMenuBO> notPidMenuBOList = EntityUtil.changeEntityListNew(HaobanMenuBO.class, notPidMenuList);
        if (CollectionUtils.isEmpty(pidMenuBOList)) {
            return new ArrayList<>();
        }
        for (HaobanMenuBO haobanMenuBO : pidMenuBOList) {
            if (CollectionUtils.isNotEmpty(notPidMenuBOList)) {
                List<HaobanMenuBO> menus = iterateMenus(notPidMenuBOList, haobanMenuBO.getMenuCode());
                haobanMenuBO.setMenuBOList(menus);
            }
        }
        return pidMenuBOList;
    }

    @Override
    public List<String> getHaobanMenuList(String wxEnterpriseId, Integer clerkType) {
        return tabHaobanMenuMapper.getHaobanMenuListByClerkType(wxEnterpriseId, clerkType, 0);
    }

    @Override
    public List<String> getHaobanMenuByPid(List<String> menuCodes) {
        List<String> list = new ArrayList<>();
        List<String> pidCodes = tabHaobanMenuMapper.getHaobanMenuCodeListByCode(menuCodes);
        List<String> childCodes = tabHaobanMenuMapper.getHaobanChildMenuCodeByPCode(menuCodes);
        list.addAll(pidCodes);
        list.addAll(childCodes);
        return list;
    }

    @Override
    public List<HaobanMenuBO> getHaobanMenuList(List<String> menuCodes) {
        if (CollectionUtils.isEmpty(menuCodes)) {
            return Collections.emptyList();
        }
        List<TabHaobanMenu> haobanMenuListByCode = tabHaobanMenuMapper.getHaobanMenuListByCode(menuCodes);
        return EntityUtil.changeEntityListNew(HaobanMenuBO.class, haobanMenuListByCode);
    }

    @Override
    public HaobanMenuBO getMenuByCode(String menuCode) {
        if (StringUtils.isBlank(menuCode)) {
            return null;
        }
        return EntityUtil.changeEntityNew(HaobanMenuBO.class, tabHaobanMenuMapper.getMenuByCode(menuCode));
    }

    @Override
    public void deleteAll() {
        tabHaobanMenuMapper.deleteAll();
    }

    public List<HaobanMenuBO> iterateMenus(List<HaobanMenuBO> menuBOList, String pCode) {
        List<HaobanMenuBO> result = new ArrayList<>();
        for (HaobanMenuBO haobanMenuBO : menuBOList) {
            String menuCode = haobanMenuBO.getMenuCode();
            String parentCode = haobanMenuBO.getParentCode();
            if (StringUtils.isNotBlank(parentCode)) {
                if (parentCode.equals(pCode)) {
                    // 递归查询当前子菜单的子菜单
                    List<HaobanMenuBO> iterateMenu = iterateMenus(menuBOList, menuCode);
                    haobanMenuBO.setMenuBOList(iterateMenu);
                    result.add(haobanMenuBO);
                }
            }
        }
        return result;
    }

    @Override
    public void deleteByMenuCode(String menuCode) {
        this.tabHaobanMenuMapper.deleteByMenuCode(menuCode);
    }

    @Override
    public void saveMenuFromGicEvent(String params) {
        logger.info("服务开通-好办小程序={}",params);
        JSONObject json = JSONObject.parseObject(params) ;
        String serviceCode = json.getString("serviceCode") ;
        String enterpriseId = json.getString("enterpriseId") ;
        String operationType = json.getString("operationType") ;
        Boolean addOrDel = null ;
        // 进行授权 auth  取消授权 cancel
        if("auth".equals(operationType)) {
            addOrDel = true;
        }
        if("cancel".equals(operationType)) {
            addOrDel = false ;
        }
        MenuListQDTO qdto = new MenuListQDTO() ;
        ServiceResponse<List<MenuDTO>> resp = this.menuApiService.listMenu(qdto) ;
        if(!resp.isSuccess()) {
            logger.info("失败={}",JSONObject.toJSONString(resp));
            return;
        }
        List<TabHaobanWxEnterpriseRelated> wxEnterpriseList = this.wxEnterpriseRelatedMapper.listByEnterpriseId(enterpriseId) ;
        if(CollectionUtils.isEmpty(wxEnterpriseList)) {
            logger.info("未关联企微={}",enterpriseId);
            return ;
        }
        logger.info("gic关联的企微={}", JSONObject.toJSONString(wxEnterpriseList));
        List<MenuDTO> menuDTOList = resp.getResult() ;
        if(CollectionUtils.isEmpty(menuDTOList)) {
            logger.info("无相关菜单");
            return ;
        }
        for(MenuDTO gicMenu : menuDTOList) {
            List<String> menuCodeList = Arrays.asList(gicMenu.getMenuCode()) ;
            List<Integer> addRoleTypeList = Arrays.asList(0,1,2);
            Date now = new Date() ;
            for(int i=0;i<wxEnterpriseList.size();i++) {
                TabHaobanWxEnterpriseRelated item = wxEnterpriseList.get(i) ;
                String wxEnterpriseId = item.getWxEnterpriseId() ;
                List<TabHaobanRoleMenu> insertMenuList = new ArrayList<>() ;
                List<TabHaobanRole> list = this.roleMapper.getListByWxEnterpriseId(wxEnterpriseId,null) ;
                TabHaobanRoleMenu menu = null ;
                for(TabHaobanRole role : list) {
                    int roleType = role.getClerkType() ;
                    if(!addRoleTypeList.contains(roleType)) {
                        continue;
                    }
                    Long roleId = role.getRoleId() ;
                    for(String menuCode : menuCodeList) {
                        // 判断是否已存在
                        List<String> oldList = this.roleMenuMapper.getMenuInMenuCodes(wxEnterpriseId,roleId,Arrays.asList(menuCode)) ;
                        if(CollectionUtils.isNotEmpty(oldList)) {
                            continue;
                        }
                        menu = new TabHaobanRoleMenu() ;
                        menu.setRoleMenuId(UniqueIdUtils.uniqueLong());
                        menu.setRoleId(roleId);
                        menu.setUpdateTime(now);
                        menu.setCreateTime(now);
                        menu.setStatusFlag(1);
                        menu.setWxEnterpriseId(wxEnterpriseId);
                        menu.setMenuCode(menuCode);
                        insertMenuList.add(menu) ;
                    }
                }
                if(CollectionUtils.isNotEmpty(insertMenuList)) {
                    this.roleMenuMapper.insertBatch(insertMenuList);
                }
            }
        }
    }
}
