package com.jeequan.jeepay.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.model.EntMatchRuleModel;
import com.jeequan.jeepay.core.model.mchconfig.MchDivisionConfig;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.service.mapper.SysRoleEntRelaMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 * 系统角色权限关联表 服务实现类
 * </p>
 *
 * @author [mybatis plus generator]
 * @since 2020-06-13
 */
@Service
public class SysRoleEntRelaService extends ServiceImpl<SysRoleEntRelaMapper, SysRoleEntRela> {

    @Autowired
    private SysEntitlementService sysEntitlementService;
    @Autowired
    private MchInfoService mchInfoService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private MchConfigService mchConfigService;
    @Autowired
    private SysUserEntruleRelaService sysUserEntruleRelaService;

    /**
     * 根据人查询出所有权限ID集合
     */
    public List<String> selectEntIdsByUserId(Long userId, Byte userType, String sysType) {

        // ↓↓↓↓↓ 1. 用户级别： 根据用户类型 或者 用户分配的 角色权限 查询出所有的权限集合  （ userEntIdList ） ↓↓↓↓↓

        List<String> userEntIdList = new ArrayList<>();

        if (userType == SysUser.UEST_TYPE_ADMIN) { // 超管查询所有的数据

            sysEntitlementService.list(SysEntitlement.gw().select(SysEntitlement::getEntId).eq(SysEntitlement::getSysType, sysType).eq(SysEntitlement::getState, CS.PUB_USABLE)
            ).forEach(r -> userEntIdList.add(r.getEntId()));


        } else if (userType == SysUser.UEST_TYPE_EXPAND) { // 扩展员

            sysEntitlementService.list(SysEntitlement.gw().select(SysEntitlement::getEntId, SysEntitlement::getMatchRule)
                    .eq(SysEntitlement::getSysType, sysType).eq(SysEntitlement::getState, CS.PUB_USABLE)
            ).forEach(r -> {

                // 查询扩展员可见的菜单集合
                if (StringUtils.isNotEmpty(r.getMatchRule())) {
                    EntMatchRuleModel entMatchRuleModel = JSONObject.parseObject(r.getMatchRule(), EntMatchRuleModel.class);
                    if (Boolean.TRUE.equals(entMatchRuleModel.getEpUserEnt())) {
                        userEntIdList.add(r.getEntId());
                    }
                }

            });

        } else if (userType == SysUser.UEST_TYPE_DIRECTOR || userType == SysUser.UEST_TYPE_CASHIER) { // 店长 & 店员

            SysUserEntruleRela sysUserEntruleRela = sysUserEntruleRelaService.getById(userId);
            String rules = sysUserEntruleRela == null ? null : sysUserEntruleRela.getRules();

            // 不等于空 && 包含数据
            if (StringUtils.isNotEmpty(rules) && !JSON.parseArray(rules).isEmpty()) {
                sysEntitlementService.lambdaQuery()
                        .select(SysEntitlement::getEntId, SysEntitlement::getMatchRule)
                        .eq(SysEntitlement::getSysType, sysType).eq(SysEntitlement::getState, CS.PUB_USABLE)
                        .list().forEach(r -> {
                            // 查询扩展员可见的菜单集合
                            if (StringUtils.isNotEmpty(r.getMatchRule())) {
                                EntMatchRuleModel entMatchRuleModel = JSONObject.parseObject(r.getMatchRule(), EntMatchRuleModel.class);
                                if (entMatchRuleModel.matchUserEntRules(rules)) {
                                    userEntIdList.add(r.getEntId());
                                }
                            }

                        });
            }

        } else { // 根据用户的角色配置权限查询
            userEntIdList.addAll(Optional.ofNullable(baseMapper.selectEntIdsByUserId(userId, sysType)).orElse(new ArrayList<>()));
        }

        // ↑↑↑↑↑ 1. 根据用户类型 或者 用户分配的 角色权限 查询出所有的权限集合  （ userEntIdList ） ↑↑↑↑↑

        // 用户数据为空
        if (userEntIdList.isEmpty()) {
            return userEntIdList;
        }


        // ↓↓↓↓↓↓↓↓↓↓ 2. 商户级别：  如果商户类型， 需要再做一个特殊判断逻辑（判断商户 分账开关、 级别等过滤条件。 ） ↓↓↓↓↓↓↓↓↓↓

        // 其他类型， 没有特殊过滤
        if (!CS.SYS_ROLE_TYPE.MCH.equals(sysType)) {
            return userEntIdList;
        }

        // 以下为：商户类型， 需要做特殊的处理 根据 userEntIdList 查询。
        List<SysEntitlement> entList = sysEntitlementService.list(SysEntitlement.gw().select(SysEntitlement::getEntId, SysEntitlement::getMatchRule)
                .eq(SysEntitlement::getSysType, sysType)
                .in(SysEntitlement::getEntId, userEntIdList));

        List<String> mchResult = new ArrayList<>();

        MchInfo mchInfo = mchInfoService.getById(sysUserService.getById(userId).getBelongInfoId());

        // 商户是否拥有用户分账管理权限
        MchDivisionConfig mchDivisionConfig = mchConfigService.queryMchDivisionConfigByDefault(mchInfo.getMchNo());

        // 商户是否拥有便捷收银台权限
        Byte mchSelfCashierConfigState = mchConfigService.getConfigValByMchNoAndKey(mchInfo.getMchNo(), MchConfig.SELF_CASHIER_STATE, Byte.class);

        // 商户是否开启会员功能
        Byte memberModelState = mchConfigService.getConfigValByMchNoAndKey(mchInfo.getMchNo(), MchConfig.SELF_MEMBER_MODEL_STATE, Byte.class);

        // 商户广告显示权限
        boolean mchAdvertEnt = true;
        // 商户便捷收银台显示权限
        boolean mchSelfCashierEnt = false;
        // 商户会员功能显示权限
        boolean mchMemberEnt = false;

        // 商户广告权限开关
        if (mchInfo.getAdvertFlag() == null || mchInfo.getAdvertFlag() == CS.NO) {
            mchAdvertEnt = false;
        }

        if (mchSelfCashierConfigState != null && mchSelfCashierConfigState == CS.YES) {
            mchSelfCashierEnt = true;
        }

        // 商户会员功能显示开关
        if (memberModelState != null && memberModelState == CS.YES) {
            mchMemberEnt = true;
        }

        // 查询到 该商户的权限配置项。
        EntMatchRuleModel mchConfigRules = EntMatchRuleModel.convertByMch(mchInfo.getType(), mchInfo.getMchLevel(),
                mchDivisionConfig.getMchDivisionEntFlag() == CS.YES, mchAdvertEnt, mchSelfCashierEnt, mchMemberEnt);
        entList.forEach(ent -> {

            // 无规则
            if (StringUtils.isEmpty(ent.getMatchRule())) {
                mchResult.add(ent.getEntId());
                return;
            }

            // 匹配成功
            if (JSON.parseObject(ent.getMatchRule(), EntMatchRuleModel.class).match(mchConfigRules)) {
                mchResult.add(ent.getEntId());
            }
        });

        return mchResult;
    }


    /**
     * 重置 角色 - 权限 关联关系
     **/
    @Transactional
    public void resetRela(String roleId, List<String> entIdList) {

        //1. 删除
        this.remove(SysRoleEntRela.gw().eq(SysRoleEntRela::getRoleId, roleId));

        //2. 插入
        for (String entId : entIdList) {
            SysRoleEntRela r = new SysRoleEntRela();
            r.setRoleId(roleId);
            r.setEntId(entId);
            this.save(r);
        }

    }


}
