package com.yunzhupaas.portal.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.base.MyBatisPrimaryBase;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.base.entity.PortalManageEntity;
import com.yunzhupaas.base.entity.SystemEntity;
import com.yunzhupaas.base.model.online.VisualMenuModel;
import com.yunzhupaas.base.model.portalManage.PortalManagePrimary;
import com.yunzhupaas.base.model.portalManage.PortalManageVO;
import com.yunzhupaas.base.service.ModuleService;
import com.yunzhupaas.base.service.PortalManageService;
import com.yunzhupaas.base.service.SuperServiceImpl;
import com.yunzhupaas.base.service.SystemService;
import com.yunzhupaas.base.util.visualUtil.PubulishUtil;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.exception.WorkFlowException;
import com.yunzhupaas.permission.entity.AuthorizeEntity;
import com.yunzhupaas.permission.entity.PermissionGroupEntity;
import com.yunzhupaas.permission.entity.UserEntity;
import com.yunzhupaas.permission.service.AuthorizeService;
import com.yunzhupaas.permission.service.PermissionGroupService;
import com.yunzhupaas.permission.service.RoleService;
import com.yunzhupaas.permission.service.UserService;
import com.yunzhupaas.portal.constant.PortalConst;
import com.yunzhupaas.portal.entity.PortalDataEntity;
import com.yunzhupaas.portal.entity.PortalEntity;
import com.yunzhupaas.portal.mapper.PortalDataMapper;
import com.yunzhupaas.portal.model.*;
import com.yunzhupaas.portal.service.PortalDataService;
import com.yunzhupaas.portal.service.PortalService;
import com.yunzhupaas.util.JsonUtil;
import com.yunzhupaas.util.JsonUtilEx;
import com.yunzhupaas.util.StringUtil;
import com.yunzhupaas.util.UserProvider;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-19
 */
@Service
public class PortalDataServiceImpl extends SuperServiceImpl<PortalDataMapper, PortalDataEntity> implements PortalDataService {

    @Autowired
    private UserService userService;
    
    @Autowired
    private PortalService portalService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private AuthorizeService authorizeService;
    @Autowired
    private PortalManageService portalManageApi;
    @Autowired
    private PermissionGroupService permissionGroupApi;
    @Autowired
    private ModuleService moduleService;
    @Autowired
    private PubulishUtil pubulishUtil;
    @Autowired
    private SystemService systemService;

    @Override
    public String getCustomDataForm(PortalCustomPrimary primary) throws Exception {
        PortalDataEntity one = getOne(primary.getQuery());
        if(one != null){
            return one.getFormData();
        }else {
            save(primary.getEntity());
        }
        return "";
    }

    @Override
    public String getModelDataForm(PortalModPrimary primary) throws Exception {
        PortalDataEntity one = getOne(primary.getQuery());
        if(one != null){
            return one.getFormData();
        }else {
            save(primary.getEntity());
        }
        return "";
    }

    @Override
    public void release(String platform, String portalId, List<String> systemIdList,String releasePlatform,PortalReleaseForm form) throws Exception {
        if(CollectionUtils.isNotEmpty(systemIdList)){
            // 系统管理对应添加绑定
            portalManageApi.createBatch(systemIdList.stream().map(systemId->
                    new PortalManagePrimary(releasePlatform, portalId, systemId)).collect(Collectors.toList()));
        }else {
            List<PortalManageVO> voList = portalManageApi.getList(new PortalManagePrimary(platform, portalId, null));
            List<String> list = systemService.getList().stream().map(SystemEntity::getId).collect(Collectors.toList());
            boolean hasSys = false;//剩下的门户对象-应用都被删除。
            for (PortalManageVO item : voList) {
                if(list.contains(item.getSystemId())){
                    hasSys = true;
                }
            }
            if (voList.size() == 0 || !hasSys) {
                throw new WorkFlowException(MsgCode.VS413.get());
            }
            systemIdList = voList.stream().map(PortalManageVO::getSystemId).collect(Collectors.toList());
        }
        String formData = "";
        try {
            formData = getModelDataForm(new PortalModPrimary(portalId));
            createOrUpdate(new PortalReleasePrimary(portalId, platform), formData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 查询所有相关的自定义数据
        for (String systemId : systemIdList) {
            List<PortalDataEntity> list = list(new PortalCustomPrimary(platform, portalId, systemId, null).getQuery());
            final String finalFormData = formData;
            if(list.size() > 0){
                // 把所有数据进行重置formData
                list.forEach(entity -> entity.setFormData(finalFormData));
                updateBatchById(list);
            }
        }
        PortalEntity info = portalService.getInfo(portalId);
        if(info!=null){
            info.setState(1);
            info.setEnabledMark(1);
            info.setPlatformRelease(form.getPlatformRelease());
            portalService.update(portalId,info);
        }
    }

    @Override
    public void releaseModule(ReleaseModel releaseModel,String portalId) throws Exception {
        PortalEntity info = portalService.getInfo(portalId);
        if(info!=null) {
            VisualMenuModel visual = new VisualMenuModel();
            visual.setApp(releaseModel.getApp());
            visual.setPc(releaseModel.getPc());
            visual.setPcModuleParentId(releaseModel.getPcModuleParentId());
            visual.setAppModuleParentId(releaseModel.getAppModuleParentId());
//            visual.setAppModuleParentId(releaseModel.getAppModuleParentId());
//            if (StringUtil.isNotEmpty(releaseModel.getPcModuleParentId()) && StringUtil.isEmpty(releaseModel.getPcSystemId())) {
//                visual.setPcModuleParentId("-1");
//            } else {
//                visual.setPcModuleParentId(releaseModel.getPcModuleParentId());
//            }
            if (releaseModel.getPc() == 1) {
                createOrUpdate(new PortalReleasePrimary(portalId, PortalConst.WEB), getModelDataForm(new PortalModPrimary(portalId)));
            }
            if (releaseModel.getApp() == 1) {
                createOrUpdate(new PortalReleasePrimary(portalId, PortalConst.APP), getModelDataForm(new PortalModPrimary(portalId)));
            }
//            visual.setPcSystemId(Optional.ofNullable(releaseModel.getPcSystemId()).orElse(releaseModel.getPcModuleParentId()));
//            visual.setAppSystemId(Optional.ofNullable(releaseModel.getAppSystemId()).orElse(releaseModel.getAppModuleParentId()));
            visual.setType(8);
            visual.setFullName(info.getFullName());
            visual.setEncode(info.getEnCode());
            visual.setId(info.getId());
            pubulishUtil.publishMenu(visual);
            info.setState(1);
            info.setEnabledMark(1);
            portalService.update(portalId,info);
        }
    }

    @Override
    public Boolean isReleaseFlag(PortalReleasePrimary primary) {
        return count(primary.getQuery()) > 0;
    }

    @Override
    public Boolean deleteAll(String portalId) {
        QueryWrapper<PortalDataEntity> query = new QueryWrapper<>();
        query.lambda().eq(PortalDataEntity::getPortalId, portalId);
        return remove(query);
    }

    /**
     * 创建或更新
     *
     *  门户ID ->（平台、系统ID、用户ID）-> 排版信息
     *  基础：门户ID绑定排版信息（一对多）、 条件：平台、系统ID、用户ID
     */
    @Override
    public void createOrUpdate(PortalCustomPrimary primary, String formData) throws Exception {
        creUpCom(primary, formData);
    }

    @Override
    public void createOrUpdate(PortalModPrimary primary, String formData) throws Exception {
        creUpCom(primary, formData);
    }

    @Override
    public void createOrUpdate(PortalReleasePrimary primary, String formData) throws Exception {
        creUpCom(primary, formData);
    }

    private void creUpCom(MyBatisPrimaryBase<PortalDataEntity> primary, String formData) throws Exception {
        // 自定义数据变量条件：0、门户 1、用户 2、系统 3、平台
        List<PortalDataEntity> list = list(primary.getQuery());
        if(list.size() < 1){
            PortalDataEntity creEntity = primary.getEntity();
            creEntity.setFormData(formData);
            save(creEntity);
        }else if(list.size() == 1){
            PortalDataEntity upEntity = list.get(0);
            upEntity.setFormData(formData);
            updateById(upEntity);
        }else {
            throw new Exception(MsgCode.VS414.get());
        }
    }

    /**
     * 根据id返回门户信息
     */
    @Override
    public PortalInfoAuthVO getDataFormView(String portalId, String platform) throws Exception{
        PortalEntity entity = portalService.getInfo(portalId);
        if (entity == null) throw new Exception(MsgCode.VS415.get());
//        if (entity.getEnabledMark() == 0) throw new Exception("门户被禁止");
        PortalInfoAuthVO infoVo = JsonUtil.getJsonToBean(JsonUtilEx.getObjectToStringDateFormat
                (entity, "yyyy-MM-dd HH:mm:ss"), PortalInfoAuthVO.class);
        // 查询自定义设计的门户信息
        infoVo.setFormData(getDataForm(platform, portalId));
        return infoVo;
    }

    private String getDataForm(String platform, String portalId) throws Exception {
        List<PortalDataEntity> dataList = list(new PortalCustomPrimary(platform, portalId).getQuery());
        if(CollectionUtil.isEmpty(dataList)) {
            dataList = list(new PortalReleasePrimary(portalId, platform).getQuery());
        }
        // 当没有自定义的排版信息时，使用已发布模板排版信息
        if(CollectionUtil.isNotEmpty(dataList)){
            PortalDataEntity entity = dataList.get(0);
            if (dataList.size() != 1) {
                List<String> ids = dataList.stream().map(PortalDataEntity::getId).collect(Collectors.toList());
                removeBatchByIds(ids.stream().filter(id -> !id.equals(entity.getId())).collect(Collectors.toList()));
            }
            return entity.getFormData();
        }
        return null;
    }

    /**
     * 设置门户默认主页
     *
     * 用户ID -> (平台、系统ID) -> 门户ID
     * 基础：用户ID绑定门户ID（多对多）、条件：平台、系统ID
     * Map格式：Map <platform:systemId, portalId>
     * @param portalId 门户ID
     * @param platform 平台
     */
    @Override
    public void setCurrentDefault(String platform, String portalId) {
        UserEntity userEntity = userService.getInfo(UserProvider.getUser().getUserId());
        Map<String, Object> map = new HashMap<>();
        try{
            map = JSONObject.parseObject(userEntity.getPortalId()).getInnerMap();
        }catch (Exception ignore){}
        if ("App".equals(platform)) {
            map.put(platform + ":" + userEntity.getAppSystemId(), portalId);
        } else {
            map.put(platform + ":" + userEntity.getSystemId(), portalId);
        }
        UserEntity update = new UserEntity();
        update.setId(userEntity.getId());
        update.setPortalId(JSONObject.toJSONString(map));
        userService.updateById(update);
    }

    @Override
    public String getCurrentDefault(String platform) throws Exception {
        UserEntity userEntity = userService.getInfo(UserProvider.getUser().getUserId());
        String systemId = PortalConst.WEB.equals(platform) ? UserProvider.getUser().getSystemId() : UserProvider.getUser().getAppSystemId();
        String portalId = "";
        try{
            Map<String, Object> map = JSONObject.parseObject(userEntity.getPortalId()).getInnerMap();
            portalId = map.get(platform + ":" + systemId).toString();
        }catch (Exception ignore){}
        PortalEntity mainPortal = portalService.getById(portalId);
        // 校验门户有效性
        if(mainPortal != null && mainPortal.getEnabledMark().equals(1)){
            // 管理员直接设置默认主页
            List<String> authPortalIds;
            if(UserProvider.getUser().getIsAdministrator()){
                List<PortalManageVO> currentVoList = portalManageApi.getListByEnable(new PortalManagePrimary(platform, null, systemId));
                authPortalIds = currentVoList.stream().map(PortalManageVO::getPortalId).collect(Collectors.toList());
            }else {
                // 获取当前用户的所有权限的门户ID集合
                authPortalIds = getCurrentAuthPortalIds(new PortalViewPrimary(platform, null));
            }
            if(CollectionUtil.isNotEmpty(authPortalIds) && authPortalIds.contains(portalId)) {
                return portalId;
            }
        }
        // 重新设置默认门户
        String updatePortalId = portalService.getModListFirstId(new PortalViewPrimary(platform, null));
        setCurrentDefault(platform, updatePortalId);
        return updatePortalId;
    }

    /**
     * 获取当下所有带权限PortalId集合
     */
    public List<String> getCurrentAuthPortalIds(PortalViewPrimary primary){
        UserInfo userInfo = UserProvider.getUser();
        String systemId = primary.getSystemId();

        // 获取用户底下所有权限portalManage
        Supplier<List<String>> authPortalManageIds = ()->{
            List<String> roleIds = permissionGroupApi.getPermissionGroupByUserId(userInfo.getUserId(), userInfo.getOrganizeId(), false, null).stream().map(PermissionGroupEntity::getId).collect(Collectors.toList());
            List<String> portalManageIds = new ArrayList<>();
            for (String roleId : roleIds) {
            /* authorize存储 portalManage->item、role->object，本质：门户管理条目与角色关系
            根据用户Id查询出对应所有的门户管理条目(distinct()进行去重) */
                List<AuthorizeEntity> authorizePortalManage = authorizeService.getListByObjectId(roleId, PortalConst.AUTHORIZE_PORTAL_MANAGE);
                portalManageIds.addAll(authorizePortalManage.stream()
                        .map(AuthorizeEntity::getItemId).distinct().collect(Collectors.toList()));
            }
            return portalManageIds;
        };

        List<String> portalManageIds = authPortalManageIds.get();

        Map<String, List<String>> map = new HashMap<>();
        // 获取具有权限的所有门户
        if(portalManageIds.size() > 0) {
            QueryWrapper<PortalManageEntity> query = new QueryWrapper<>();
            query.lambda().eq(PortalManageEntity::getEnabledMark, 1)
                          .eq(PortalManageEntity::getPlatform, primary.getPlatForm())
                          .in(PortalManageEntity::getId, portalManageIds);
            List<PortalManageEntity> portalManageList = portalManageApi.list(query);
            Map<String, List<PortalManageEntity>> collect = portalManageList.stream().collect(Collectors.groupingBy(PortalManageEntity::getSystemId));
            // key:systemId 、 value:portalIdList
            collect.forEach((key, description) -> map.put(key, description.stream().map(PortalManageEntity::getPortalId).collect(Collectors.toList())));
            return map.get(systemId);
        }else {
            return new ArrayList<>();
        }
    }

    /* ============== 目前使用懒加载更新主页，故注释 =============== */
//    /**
//     *  校验：当前用户的默认门户首页是否还具备权限
//     *  （当权限被删除，默认首页丢失）
//     */
//    private void checkDefaultPortal(List<String> originRoleIds, List<String> updateRoleIds, String portalManageId){
//        // 若是新增角色不会对默认门户产生影响
//        List<String> delRoleIds = originRoleIds.stream().filter(o -> !updateRoleIds.contains(o))
//                .collect(Collectors.toList());
//        if(CollectionUtil.isNotEmpty(delRoleIds)){
//            // 授权取消所涉及到用户集合
//            List<UserEntity> userList = userService.getListByRoleIds(delRoleIds);
//            for (UserEntity userEntity : userList) {
//                String userId = userEntity.getId();
//                // 获取各系统下带权限的门户ID（这里跨服务会产生数据不同步的问题）
//                Map<String, List<String>> authorizeSysPortalIdsMap = getAuthorizePortalIds(userId);
//                // 获取原始各系统下默认门户ID
//                Map<String, String> sysDefaultPortalIdMap = portalManageService.getDefault(userEntity.getId());
//                for (Map.Entry<String, String> defaultMap : sysDefaultPortalIdMap.entrySet()) {
//                    String systemId = defaultMap.getKey();
//                    // 默认门户ID
//                    String defaultPortalId = defaultMap.getValue();
//                    // 带权限门户ID
//                    List<String> authorizePortalIds = authorizeSysPortalIdsMap.get(systemId);
//                    if(CollectionUtil.isNotEmpty(authorizePortalIds)){
//                        if(!authorizePortalIds.contains(defaultPortalId)){
//                            // 丢失默认门户，顺位首个
//                            portalManageService.setDefault(userId, systemId, authorizePortalIds.get(0));
//                        }
//                    }
//                }
//            }
//        }
//    }



}

