package com.njzscloud.supervisory.sys.role.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.mp.support.PageResult;
import com.njzscloud.supervisory.constant.Constant;
import com.njzscloud.supervisory.sys.role.mapper.RoleMapper;
import com.njzscloud.supervisory.sys.role.pojo.entity.RoleEntity;
import com.njzscloud.supervisory.sys.role.pojo.entity.RoleResourceEntity;
import com.njzscloud.supervisory.sys.role.pojo.param.RoleAddParam;
import com.njzscloud.supervisory.sys.role.pojo.param.RoleModifyParam;
import com.njzscloud.supervisory.sys.role.pojo.param.RoleQueryParam;
import com.njzscloud.supervisory.sys.role.pojo.result.RoleDetailResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

import static com.njzscloud.common.security.contant.Constants.ROLE_ADMIN;

/**
 * 角色表
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RoleService extends ServiceImpl<RoleMapper, RoleEntity> implements IService<RoleEntity> {
    private final RoleResService roleResService;

    /**
     * 新增
     */
    @Transactional(rollbackFor = Exception.class)
    public Long add(RoleAddParam roleAddParam) {
        RoleEntity roleEntity = BeanUtil.copyProperties(roleAddParam, RoleEntity.class);
        String roleCode = roleEntity.getRoleCode();
        if (!roleCode.startsWith("ROLE_")) {
            roleCode = "ROLE_" + roleCode;
            roleEntity.setRoleCode(roleCode);
        }
        boolean exists = this.exists(Wrappers.<RoleEntity>lambdaQuery().eq(RoleEntity::getRoleCode, roleCode));
        String roleCode_ = roleCode;
        Assert.isFalse(exists, () -> Exceptions.clierr("角色编码：{} 已存在", roleCode_));
        this.save(roleEntity);

        Long roleEntityId = roleEntity.getId();
        List<Long> resIds = roleAddParam.getResIds();
        roleResService.bindRes(roleEntityId, resIds);
        return roleEntityId;
    }

    /**
     * 修改
     */
    @Transactional(rollbackFor = Exception.class)
    public void modify(RoleModifyParam roleModifyParam) {
        Long roleId = roleModifyParam.getId();
        boolean exists = this.exists(Wrappers.<RoleEntity>lambdaQuery().eq(RoleEntity::getId, roleId));
        Assert.isTrue(exists, () -> Exceptions.clierr("角色不存在"));
        RoleEntity roleEntity = BeanUtil.copyProperties(roleModifyParam, RoleEntity.class);
        this.updateById(roleEntity);
        List<Long> resIds = roleModifyParam.getResIds();
        roleResService.bindRes(roleId, resIds);
    }

    /**
     * 删除
     */
    @Transactional(rollbackFor = Exception.class)
    public void del(List<Long> ids) {
        Assert.notEmpty(ids, () -> Exceptions.clierr("未指定要删除的数据"));
        List<RoleEntity> list = this.listByIds(ids);
        Assert.isFalse(list.stream().anyMatch(it -> {
                    String roleCode = it.getRoleCode();
                    return roleCode.equals(ROLE_ADMIN)
                            || roleCode.equals(Constant.ROLE_SHORT_BARGE)
                            || roleCode.equals(Constant.ROLE_STATION_MANAGE)
                            || roleCode.equals(Constant.ROLE_JG)
                            ;
                }
        ), () -> Exceptions.exception("管理员角色不允许删除"));
        this.removeBatchByIds(ids);
        roleResService.remove(Wrappers.<RoleResourceEntity>lambdaQuery().in(RoleResourceEntity::getRoleId, ids));
    }

    /**
     * 详情
     */
    public RoleDetailResult detail(Long id) {
        RoleEntity roleEntity = this.getById(id);
        List<RoleResourceEntity> list = roleResService.list(Wrappers.<RoleResourceEntity>lambdaQuery().eq(RoleResourceEntity::getRoleId, id));
        List<Long> resIds = list.stream().map(RoleResourceEntity::getResId).collect(Collectors.toList());
        return BeanUtil.copyProperties(roleEntity, RoleDetailResult.class)
                .setResIds(resIds);
    }

    /**
     * 分页查询
     */
    public PageResult<RoleDetailResult> paging(IPage<RoleEntity> page, RoleQueryParam roleQueryParam) {
        String roleCode = roleQueryParam.getRoleCode();
        String roleName = roleQueryParam.getRoleName();
        Wrapper<RoleEntity> ew = Wrappers.<RoleEntity>lambdaQuery()
                .like(StrUtil.isNotBlank(roleCode), RoleEntity::getRoleCode, roleCode)
                .like(StrUtil.isNotBlank(roleName), RoleEntity::getRoleName, roleName);
        return PageResult.of(baseMapper.paging(page, ew).convert(it -> BeanUtil.copyProperties(it, RoleDetailResult.class)));
    }
}
