package cn.superdesk.uniorder.service._permission.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.common.mq.redis.service.RedisManager;
import cn.superdesk.uniorder.common.numerical.AnLongUtils;
import cn.superdesk.uniorder.common.numerical.AnStringUtils;
import cn.superdesk.uniorder.common.security.JwtUtil;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.organisation.SysEnterprise;
import cn.superdesk.uniorder.dao.entity.organisation.SysEnterpriseExample;
import cn.superdesk.uniorder.dao.entity.organisation.SysOrganization;
import cn.superdesk.uniorder.dao.entity.setting.UnifiedService;
import cn.superdesk.uniorder.dao.entity.sys.SysUser;
import cn.superdesk.uniorder.dao.entity.sys.role.SysRoleExtData;
import cn.superdesk.uniorder.dao.entity.sys.role.SysRoleExtDataSample;
import cn.superdesk.uniorder.dao.mapper.organisation.SysEnterpriseMapper;
import cn.superdesk.uniorder.dto.vo._function.select.SelectOptionOrg;
import cn.superdesk.uniorder.dto.vo._function.select.SelectOptionVirt;
import cn.superdesk.uniorder.service._permission.PermissionService;
import cn.superdesk.uniorder.service.organisation.SysEnterpriseService;
import cn.superdesk.uniorder.service.organisation.SysOrganizationService;
import cn.superdesk.uniorder.service.setting.UnifiedServiceService;
import cn.superdesk.uniorder.service.sys.SysUserService;
import cn.superdesk.uniorder.service.sys.role.SysRoleExtDataService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;


/**
 * @Description: 权限相关
 * @Author: linjinyu
 * @CreateDate: 9/4/20 2:47 PM
 * @UpdateUser: linjinyu
 * @UpdateDate: 9/4/20 2:47 PM
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class PermissionServiceImpl implements PermissionService {


    @Resource
    private SysOrganizationService sysOrganizationService;
    @Resource
    private SysEnterpriseService   sysEnterpriseService;
    @Autowired
    private SysEnterpriseMapper    sysEnterpriseMapper;
    @Autowired
    private SysUserService         sysUserService;
    @Autowired
    private SysRoleExtDataService  sysRoleExtDataService;
    @Autowired
    private UnifiedServiceService  unifiedServiceService;


    @Resource
    private RedisManager redisManager;


    /**
     * @param outOrgIds
     * @return
     */
    @Override
    public List<SelectOptionOrg> convertSelectPermOrg(List<Long> outOrgIds) {

        // 去重
        List<Long> outOrgIdsDistinct = outOrgIds.stream().distinct().collect(Collectors.toList());

        log.info("\nDistinct\nbefore : {}\nafter : {}\n", JSONUtil.toJsonStr(outOrgIds), JSONUtil.toJsonStr(outOrgIdsDistinct));

        List<SelectOptionOrg> selectPermOrg = new ArrayList<>();

        List<SysOrganization> result = sysOrganizationService.findByOutOrgIds(outOrgIdsDistinct);

        if (CollUtil.isNotEmpty(result)) {
            for (SysOrganization entity : result) {

                SelectOptionOrg opt = new SelectOptionOrg();
                opt.setSysOrgId(entity.getId());
                opt.setProjectId(entity.getOrganizationId());
                opt.setProjectName(entity.getOrganizationName());

                selectPermOrg.add(opt);

            }
        }


        return selectPermOrg;
    }


    /**
     * @param outVirtIds
     * @return
     */
    @Override
    public List<SelectOptionVirt> convertSelectPermVirt(List<Long> outVirtIds) {

        // 去重 Long
        List<Long> outVirtIdsDistinct = outVirtIds.stream().distinct().collect(Collectors.toList());

        log.info("\nDistinct\nbefore : {}\nafter : {}\n", JSONUtil.toJsonStr(outVirtIds), JSONUtil.toJsonStr(outVirtIdsDistinct));

        List<SelectOptionVirt> selectPermVirt = new ArrayList<>();

        List<SysEnterprise> result = sysEnterpriseService.findByOutVirtIds(outVirtIds);

        if (CollUtil.isNotEmpty(result)) {
            for (SysEnterprise entity : result) {

                SelectOptionVirt opt = new SelectOptionVirt();

                opt.setOutOrgId(entity.getOrganizationId());
                opt.setSysVirtId(entity.getId());
                opt.setVirtId(entity.getEnterpriseId());
                opt.setVirtName(entity.getEnterpriseName());

                selectPermVirt.add(opt);
            }
        }

        return selectPermVirt;
    }


//	Map<String, Object> tokenVo = JwtUtil.getTokenVo(getToken());

    @Override
    public String getPermOutOrgIds(String token) {

        LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(token);

        String mapValueForRedis = redisManager.getTokenInfoOutOrgIdsCache(loginSysUser.getSysUserName());

        log.info("\ngetPermOutOrgIds \nString :{}\n", mapValueForRedis);

        return mapValueForRedis;

    }

    @Override
    public String getPermOutVirtIds(String token) {

        LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(token);

        String mapValueForRedis = redisManager.getTokenInfoOutVirtIdsCache(loginSysUser.getSysUserName());

        log.info("\ngetPermOutVirtIds \nString :{}\n", mapValueForRedis);

        return mapValueForRedis;

    }

    /**
     * TODO 还要重构
     *
     * @param token
     * @return
     */
    @Override
    public List<SelectOptionOrg> getSelectPermOrgByToken(String token) {

        List<SelectOptionOrg> selectPermOrg = new ArrayList<>();

        LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(token);

        String mapValueForRedis = redisManager.getTokenInfoSelectPermOrgCache(loginSysUser.getSysUserName());

        selectPermOrg = AnJsonUtils.toList(mapValueForRedis, SelectOptionOrg.class);

        log.info("\ngetSelectPermOrgByToken \nString :{}\nList : {}\n", mapValueForRedis, JSONUtil.toJsonStr(selectPermOrg));

        return selectPermOrg;

    }

    /**
     * TODO 还要重构
     *
     * @param token
     * @return
     */
    @Override
    public List<SelectOptionVirt> getSelectPermVirtByToken(String token) {

        List<SelectOptionVirt> selectOptionPermVirt = new ArrayList<>();
        List<SelectOptionVirt> filterOptionPermVirt = new ArrayList<>();

        LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(token);

        String mapValueForRedis = redisManager.getTokenInfoSelectPermVirtCache(loginSysUser.getSysUserName());

        selectOptionPermVirt = AnJsonUtils.toList(mapValueForRedis, SelectOptionVirt.class);

        selectOptionPermVirt = selectOptionPermVirt
                .stream()
                .distinct()
                .collect(Collectors.toList());

        log.info("\ngetSelectPermVirtByToken \nString :{}\nList : {}\n", mapValueForRedis, JSONUtil.toJsonStr(selectOptionPermVirt));


        // TODO 过滤 没有订单 | 但如果没有更新过 就不会触发 禁用 删除
        if (CollUtil.isNotEmpty(selectOptionPermVirt)) {

            List<Long> rangeOutVirtIds = selectOptionPermVirt
                    .stream()
                    .map(SelectOptionVirt::getVirtId)
                    .distinct()
                    .collect(Collectors.toList());
            List<Integer> c = new ArrayList<>();
            c.add(0);
            c.add(1);

            SysEnterpriseExample example = new SysEnterpriseExample();
            example.createCriteria()
                    .andEnterpriseIdIn(rangeOutVirtIds)
                    .andIsHasOrderIn(c);

//            example.setOrderByClause("");

            List<SysEnterprise> filterPermVirt = sysEnterpriseMapper.selectByExample(example);

            if (CollUtil.isNotEmpty(filterPermVirt)) {

                filterPermVirt.forEach(item -> {

                    filterOptionPermVirt.add(SelectOptionVirt
                            .builder()

                            .outOrgId(item.getOrganizationId())
                            .sysVirtId(item.getId())
                            .virtId(item.getEnterpriseId())
                            .virtName(item.getEnterpriseName())

                            .sourceFrom(item.getSourceFrom())
                            .serviceNo(item.getServiceNo())

                            .build()
                    );
                });

                return filterOptionPermVirt;
            }
        }


        return selectOptionPermVirt;
    }


    /**
     * 订单类型 下拉 权限
     *
     * @param token
     * @return
     */
    @Override
    public List<UnifiedService> getAsOrderType(String token) {

        // 如果是 统一订单用户 没有这个就是全部
        // 如果是 服务之窗用户 没有这个就是没有

        // 初始化
        List<String>               selectServiceNo          = new ArrayList<>();
        List<SysRoleExtDataSample> sysRoleExtDataSampleList = new ArrayList<>();
        List<UnifiedService>       resultList               = new ArrayList<>();
        List<UnifiedService>       responseList             = new ArrayList<>();

        // 当前用户
        LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(token);


        // 当前用户信息

        String mapValueForRedisRoleId = redisManager.getTokenInfoRoleIdCache(loginSysUser.getSysUserName());

        /****************************************** 从这个角色想要得到serviceNo是错的 start ******************************************/
//		String mapValueForRedisSysRoleExtDataSampleList = (String) redisService.hgetKey(redisService.getCacheKey(RedisKeyPrefix.TOKEN_CACHE, loginSysUser.getSysUserName()), "sysRoleExtDataSampleList");
//		sysRoleExtDataSampleList = JsonUtils.toList(mapValueForRedisSysRoleExtDataSampleList, SysRoleExtDataSample.class);
//
//		log.info("\ngetSelectServiceNoByToken \nString :{}\nList : {}\n", mapValueForRedisSysRoleExtDataSampleList, JsonUtils.toJson(sysRoleExtDataSampleList));
//
//		if (CollUtil.isNotEmpty(sysRoleExtDataSampleList)) {
//			selectServiceNo = sysRoleExtDataSampleList.stream().map(SysRoleExtDataSample::getServiceNo).distinct().collect(Collectors.toList());
//		}
        /****************************************** 从这个角色想要得到serviceNo是错的   end ******************************************/

        /****************************************** 修改为 start ******************************************/

        SysUser        sysUser        = sysUserService.findById(loginSysUser.getSysUserId());
        SysRoleExtData sysRoleExtData = null;

        if (null != sysUser && null != sysUser.getSysRoleExtDataId()) {
            sysRoleExtData = sysRoleExtDataService.findSysRoleExtDataById(sysUser.getSysRoleExtDataId());

            if (null != sysRoleExtData && StringUtils.isNotBlank(sysRoleExtData.getServiceNoMult())) {
                selectServiceNo = AnStringUtils.stringArrayConvertToStringList(sysRoleExtData.getServiceNoMult(), ",");
            }
        }


        /****************************************** 修改为 start ******************************************/

        resultList = unifiedServiceService.getAsOrderType();

        final List<String> finalServiceNo = selectServiceNo;

        // 处理没有设定的情况
        if (CollUtil.isEmpty(selectServiceNo)) {

            // 为了说明情况写成这样
            // 以用户角色分情况
            // 情况一
            if (AnLongUtils.getLong(mapValueForRedisRoleId).compareTo(/*14 运营商*/14L) == 0 || AnLongUtils.getLong(mapValueForRedisRoleId).compareTo(/*15 渠道商*/15L) == 0) {

            }
            // 情况二
            else {
                responseList = resultList;
            }
        }
        // 处理有设定的情况 有设定处于都一样
        else {

            List<Predicate<UnifiedService>> predicatesIn = new ArrayList<>();
            predicatesIn.add(r -> finalServiceNo.contains(r.getServiceNo()));
            responseList = AnLamdaUtils.filters(resultList, predicatesIn);

        }

        log.info("\n\nPermissionServiceImpl -> getAsOrderType\n{}\n{}\n{}\nresponse :: {}\n", JSONUtil.toJsonStr(sysRoleExtDataSampleList), JSONUtil.toJsonStr(finalServiceNo), mapValueForRedisRoleId, AnJsonUtils.toPrettyJson(responseList));

        return responseList;

    }


    /****************************************** 供应商 start ******************************************/

    @Override
    public String getPermOutSaleId(String token) {

        LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(token);

        String mapValueForRedis = redisManager.getTokenInfoOutSaleIdCache(loginSysUser.getSysUserName());

        log.info("\ngetPermOutSaleId \nString :{}\n", mapValueForRedis);

        return mapValueForRedis;

    }

    @Override
    public String getPermOutSaleName(String token) {

        LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(token);

        String mapValueForRedis = redisManager.getTokenInfoOutSaleNameCache(loginSysUser.getSysUserName());

        log.info("\ngetPermOutSaleName \nString :{}\n", mapValueForRedis);

        return mapValueForRedis;

    }


    // TODO 还要要做个整体的会方便一点 伪代码 关键字 userLoginCommon
//	public void getXXX(){
//		mapValueForRedis.put("userId", responseVo.getId().toString());
//		mapValueForRedis.put("loginSysUser.getSysUserName()", responseVo.getloginSysUser.getSysUserName()());
//		mapValueForRedis.put("fullname", responseVo.getFullname());
//		mapValueForRedis.put("token", responseVo.getToken());
//		mapValueForRedis.put("refreshToken", responseVo.getRefreshToken());
//		mapValueForRedis.put("createTime", createTime);
//		mapValueForRedis.put("updateTime", createTime);
//
//		/****************************************** 角色 菜单按扭权限 start  ******************************************/
//		mapValueForRedis.put("roleId", responseVo.getRoleId().toString());
//		/****************************************** 角色 菜单按扭权限   end  ******************************************/
//
//		/****************************************** 角色 数据权限 start  ******************************************/
//		mapValueForRedis.put("sysOrgIds", sysOrgIds);
//		mapValueForRedis.put("sysOrgNames", sysOrgNames);
//		mapValueForRedis.put("sysVirtIds", sysVirtIds);
//		mapValueForRedis.put("sysVirtNames", sysVirtNames);
//		mapValueForRedis.put("outOrgIds", outOrgIds);
//		mapValueForRedis.put("outOrgNames", outOrgNames);
//		mapValueForRedis.put("outVirtIds", outVirtIds);
//		mapValueForRedis.put("outVirtNames", outVirtNames);
//
//		mapValueForRedis.put("selectPermOrg", JsonUtils.toJson(selectPermOrg));
//		mapValueForRedis.put("selectPermVirt", JsonUtils.toJson(selectPermVirt));
//
//		mapValueForRedis.put("sysRoleExtData", JsonUtils.toJson(sysRoleExtData));
//		mapValueForRedis.put("sysRoleExtDataSampleList", JsonUtils.toJson(sysRoleExtDataSampleList));
//		/****************************************** 角色 数据权限   end  ******************************************/
//		mapValueForRedis.put("expireTime", AnDateHelper.formatDateToStr(token.getExpireTime()));
//        mapValueForRedis.put("outLogin", "0");
//	redisService.saveHash(mapValueForRedis, RedisKeyPrefix.TOKEN_CACHE, responseVo.getloginSysUser.getSysUserName()(), SystemConsts.RedisExpireTime.REFRESH_TOKEN_EXPIRE_TIME);
//	}


}
