package top.tqx.demo_1.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.tqx.demo_1.constant.CommonConstant;
import top.tqx.demo_1.dto.RoleCreateRequest;
import top.tqx.demo_1.dto.RoleUpdateRequest;
import top.tqx.demo_1.entity.Permission;
import top.tqx.demo_1.entity.Role;
import top.tqx.demo_1.entity.RolePermission;
import top.tqx.demo_1.mapper.PermissionMapper;
import top.tqx.demo_1.mapper.RoleMapper;
import top.tqx.demo_1.mapper.RolePermissionMapper;
import top.tqx.demo_1.service.RoleService;
import top.tqx.demo_1.vo.PermissionVO;
import top.tqx.demo_1.vo.RoleVO;

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

@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    
    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public List<RoleVO> listRoles() {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getStatus, CommonConstant.STATUS_ENABLE);
        wrapper.orderByAsc(Role::getRoleType, Role::getId);
        
        List<Role> roles = this.list(wrapper);
        return roles.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createRole(RoleCreateRequest request) {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getRoleCode, request.getRoleCode());
        if (this.count(wrapper) > 0) {
            throw new RuntimeException("角色编码已存在");
        }
        
        Role role = new Role();
        BeanUtils.copyProperties(request, role);
        role.setStatus(CommonConstant.STATUS_ENABLE);
        role.setCreateTime(LocalDateTime.now());
        
        this.save(role);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRole(Long id, RoleUpdateRequest request) {
        Role role = this.getById(id);
        if (role == null) {
            throw new RuntimeException("角色不存在");
        }
        
        BeanUtils.copyProperties(request, role, "createTime");
        this.updateById(role);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRole(Long id) {
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, id);
        rolePermissionMapper.delete(wrapper);
        
        this.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignPermissions(Long roleId, List<Long> permissionIds) {
        Role role = this.getById(roleId);
        if (role == null) {
            throw new RuntimeException("角色不存在");
        }
        
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, roleId);
        rolePermissionMapper.delete(wrapper);
        
        if (permissionIds != null && !permissionIds.isEmpty()) {
            for (Long permissionId : permissionIds) {
                RolePermission rolePermission = new RolePermission();
                rolePermission.setRoleId(roleId);
                rolePermission.setPermissionId(permissionId);
                rolePermission.setCreateTime(LocalDateTime.now());
                rolePermissionMapper.insert(rolePermission);
            }
        }
    }

    @Override
    public List<PermissionVO> getRolePermissions(Long roleId) {
        List<Permission> permissions = rolePermissionMapper.selectPermissionsByRoleId(roleId);
        return permissions.stream()
                .map(this::convertToPermissionVO)
                .collect(Collectors.toList());
    }

    private RoleVO convertToVO(Role role) {
        RoleVO vo = new RoleVO();
        BeanUtils.copyProperties(role, vo);
        return vo;
    }
    
    private PermissionVO convertToPermissionVO(Permission permission) {
        PermissionVO vo = new PermissionVO();
        BeanUtils.copyProperties(permission, vo);
        return vo;
    }
}
