package com.simuwang.manage.service.impl.system;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.simuwang.base.common.support.MybatisPage;
import com.simuwang.base.common.support.command.BaseAddCmd;
import com.simuwang.base.common.support.command.BaseEditCmd;
import com.simuwang.base.common.support.command.BaseIdStatusCmd;
import com.simuwang.base.common.support.command.BaseIdsCmd;
import com.simuwang.base.common.support.dos.OnlyIdNameDO;
import com.simuwang.base.common.support.query.PageQuery;
import com.simuwang.base.common.support.service.IService;
import com.simuwang.base.common.support.vo.OnlyIdNameVO;
import com.simuwang.base.components.UserAuthService;
import com.simuwang.base.mapper.system.SysRoleMapper;
import com.simuwang.base.pojo.dos.sys.SysRoleDO;
import com.simuwang.base.pojo.dto.GetByIdQuery;
import com.simuwang.base.pojo.dto.sys.RoleAddCmd;
import com.simuwang.base.pojo.dto.sys.RoleEditCmd;
import com.simuwang.base.pojo.dto.sys.RoleMenuAssignCmd;
import com.simuwang.base.pojo.dto.sys.RoleQuery;
import com.simuwang.base.pojo.vo.sys.SysRoleVO;
import com.simuwang.manage.service.system.SysRoleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

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

@Service
public class SysRoleServiceImpl implements SysRoleService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private final SysRoleMapper mapper;
    private final UserAuthService userAuthService;

    public SysRoleServiceImpl(SysRoleMapper mapper, UserAuthService userAuthService) {
        this.mapper = mapper;
        this.userAuthService = userAuthService;
    }

    @Override
    public String[] selectColumns() {
        return IService.extColumns(DEFAULT_SELECT_COLUMNS, "role_id", "role_name", "role_sort", "role_key", "status");
    }

    @Override
    public <Q extends PageQuery> void wrapQuery(QueryWrapper<SysRoleDO> wrapper, Q query) {
        // 排除超级管理员
        wrapper.ne("role_id", 1).notIn("role_key", "SYSTEM", "ADMIN");
        RoleQuery params = (RoleQuery) query;
        String keyword = params.getKeyword();
        if (StrUtil.isNotBlank(keyword)) {
            wrapper.like("role_name", keyword);
        }
        if (params.getStatus() != null) {
            wrapper.eq("status", params.getStatus());
        }
    }

    @Override
    public MybatisPage<SysRoleVO> convertPage(Page<SysRoleDO> page, QueryWrapper<SysRoleDO> wrapper) {
        IPage<SysRoleDO> entityPage = this.mapper.selectPage(page, wrapper);
        return MybatisPage.ofList(entityPage, SysRoleDO::toVo);
    }

    @Override
    public <C extends BaseAddCmd<SysRoleDO>> void insert(C command) {
        RoleAddCmd cmd = (RoleAddCmd) command;
        SysRoleDO entity = cmd.toEntity();
        this.mapper.insert(entity);
    }

    @Override
    public <C extends BaseEditCmd<SysRoleDO>> void update(C command) {
        RoleEditCmd cmd = (RoleEditCmd) command;
        SysRoleDO entity = cmd.toEntity();
        this.mapper.updateById(entity);
    }

    @Override
    public <C extends BaseIdStatusCmd> void updateStatus(C command) {
        SysRoleDO entity = new SysRoleDO();
        entity.setRoleId(command.getId());
        entity.setStatus(command.getStatus());
        this.mapper.updateById(entity);
    }

    @Override
    public <C extends BaseIdsCmd> void delete(C command) {
        List<Integer> ids = command.getIds();
        this.mapper.deleteByIds(ids);
    }

    @Override
    public void assignPerms(RoleMenuAssignCmd command) {
        Integer roleId = command.getRoleId();
        int i = this.mapper.delRoleMenuByUserId(roleId);
        int j = this.mapper.batchRoleMenus(roleId, command.getMenuIds());
        if (this.logger.isInfoEnabled()) {
            this.logger.info("给{}角色分配权限时删除了{}条记录，新增{}条记录", roleId, i, j);
        }
    }

    @Override
    public List<OnlyIdNameVO> getRolePerms(GetByIdQuery query) {
        List<OnlyIdNameDO> dataList = this.userAuthService.roleAssignPerms(query.getId());
        return dataList.stream().map(OnlyIdNameDO::toVo).collect(Collectors.toList());
    }
}
