package com.competition.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.competition.common.enums.ErrorCode;
import com.competition.common.exception.BusinessException;
import com.competition.common.result.PageResult;
import com.competition.modules.sys.dto.CreateRoleDto;
import com.competition.modules.sys.dto.UpdateRoleDto;
import com.competition.modules.sys.entity.SysPermission;
import com.competition.modules.sys.entity.SysRole;
import com.competition.modules.sys.entity.SysRolePermission;
import com.competition.modules.sys.mapper.SysPermissionMapper;
import com.competition.modules.sys.mapper.SysRoleMapper;
import com.competition.modules.sys.mapper.SysRolePermissionMapper;
import com.competition.modules.sys.service.ISysRoleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Slf4j
@Service
@RequiredArgsConstructor
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {

    private final SysRolePermissionMapper rolePermissionMapper;
    private final SysPermissionMapper permissionMapper;

    @Override
    @Transactional
    public Map<String, Object> createRole(CreateRoleDto dto, Long tenantId) {
        log.info("开始创建角色，名称：{}，租户：{}", dto.getName(), tenantId);

        SysRole role = new SysRole();
        role.setTenantId(tenantId);
        role.setName(dto.getName());
        role.setCode(dto.getCode());
        role.setDescription(dto.getDescription());
        baseMapper.insert(role);

        // 创建权限关联
        if (dto.getPermissionIds() != null) {
            for (Long permId : dto.getPermissionIds()) {
                SysRolePermission rp = new SysRolePermission();
                rp.setRoleId(role.getId());
                rp.setPermissionId(permId);
                rolePermissionMapper.insert(rp);
            }
        }

        log.info("角色创建成功，ID：{}", role.getId());
        return findDetail(role.getId(), tenantId);
    }

    @Override
    public PageResult<Map<String, Object>> findAll(Long page, Long pageSize, Long tenantId) {
        IPage<SysRole> result = baseMapper.selectPage(
                new Page<>(page, pageSize),
                new LambdaQueryWrapper<SysRole>()
                        .eq(tenantId != null, SysRole::getTenantId, tenantId)
                        .eq(SysRole::getValidState, 1)
                        .orderByDesc(SysRole::getCreateTime)
        );

        List<Map<String, Object>> list = new ArrayList<>();
        for (SysRole role : result.getRecords()) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", role.getId());
            map.put("tenantId", role.getTenantId());
            map.put("name", role.getName());
            map.put("code", role.getCode());
            map.put("description", role.getDescription());
            map.put("validState", role.getValidState());
            map.put("createTime", role.getCreateTime());

            // 附加权限列表
            List<SysRolePermission> rps = rolePermissionMapper.selectList(
                    new LambdaQueryWrapper<SysRolePermission>().eq(SysRolePermission::getRoleId, role.getId()));
            List<SysPermission> permissions = new ArrayList<>();
            for (SysRolePermission rp : rps) {
                SysPermission perm = permissionMapper.selectById(rp.getPermissionId());
                if (perm != null) permissions.add(perm);
            }
            map.put("permissions", permissions);

            list.add(map);
        }

        return new PageResult<>(list, result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    public Map<String, Object> findDetail(Long id, Long tenantId) {
        SysRole role = getById(id);
        if (role == null) {
            throw BusinessException.of(ErrorCode.NOT_FOUND, "角色不存在");
        }

        Map<String, Object> map = new HashMap<>();
        map.put("id", role.getId());
        map.put("tenantId", role.getTenantId());
        map.put("name", role.getName());
        map.put("code", role.getCode());
        map.put("description", role.getDescription());
        map.put("validState", role.getValidState());
        map.put("createTime", role.getCreateTime());

        // 附加权限列表
        List<SysRolePermission> rps = rolePermissionMapper.selectList(
                new LambdaQueryWrapper<SysRolePermission>().eq(SysRolePermission::getRoleId, id));
        List<SysPermission> permissions = new ArrayList<>();
        for (SysRolePermission rp : rps) {
            SysPermission perm = permissionMapper.selectById(rp.getPermissionId());
            if (perm != null) permissions.add(perm);
        }
        map.put("permissions", permissions);

        return map;
    }

    @Override
    @Transactional
    public Map<String, Object> updateRole(Long id, UpdateRoleDto dto, Long tenantId) {
        log.info("开始更新角色，ID：{}", id);
        SysRole existing = getById(id);
        if (existing == null) {
            throw BusinessException.of(ErrorCode.NOT_FOUND, "角色不存在");
        }

        SysRole role = new SysRole();
        role.setId(id);
        if (dto.getName() != null) role.setName(dto.getName());
        if (dto.getCode() != null) role.setCode(dto.getCode());
        if (dto.getDescription() != null) role.setDescription(dto.getDescription());
        baseMapper.updateById(role);

        // 更新权限关联
        if (dto.getPermissionIds() != null) {
            rolePermissionMapper.delete(
                    new LambdaQueryWrapper<SysRolePermission>().eq(SysRolePermission::getRoleId, id));
            for (Long permId : dto.getPermissionIds()) {
                SysRolePermission rp = new SysRolePermission();
                rp.setRoleId(id);
                rp.setPermissionId(permId);
                rolePermissionMapper.insert(rp);
            }
        }

        return findDetail(id, tenantId);
    }

    @Override
    public void removeRole(Long id, Long tenantId) {
        log.info("删除角色，ID：{}", id);
        SysRole role = getById(id);
        if (role == null) {
            throw BusinessException.of(ErrorCode.NOT_FOUND, "角色不存在");
        }
        removeById(id);
    }
}
