package com.saas.admin.controller;

import com.saas.admin.dto.request.AssignPermissionsRequest;
import com.saas.admin.dto.request.CreateRoleRequest;
import com.saas.admin.dto.request.UpdateRoleRequest;
import com.saas.admin.dto.response.RoleResponse;
import com.saas.admin.entity.Role;
import com.saas.admin.service.RBACService;
import com.saas.shared.dto.mapper.RoleMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/admin/roles")
@PreAuthorize("hasRole('SYSTEM_ADMIN')")
@Tag(name = "Admin Roles", description = "Role management for RBAC system")
@Slf4j
@RequiredArgsConstructor
public class AdminRoleController {
    
    private final RBACService rbacService;
    private final RoleMapper roleMapper;
    
    @PostMapping
    @Operation(summary = "Create role")
    public ResponseEntity<RoleResponse> createRole(@Valid @RequestBody CreateRoleRequest request) {
        log.info("Admin creating role: {}", request.getName());
        
        Role role = rbacService.createRole(request.getName(), request.getDescription(), request.getIsSystem());
        RoleResponse response = roleMapper.toResponse(role);
        
        return ResponseEntity.status(HttpStatus.CREATED).body(response);
    }
    
    @GetMapping
    @Operation(summary = "Get all roles")
    public ResponseEntity<List<RoleResponse>> getAllRoles() {
        List<Role> roles = rbacService.getAllRoles();
        List<RoleResponse> responses = roleMapper.toResponseList(roles);
        return ResponseEntity.ok(responses);
    }
    
    @GetMapping("/{id}")
    @Operation(summary = "Get role by ID")
    public ResponseEntity<RoleResponse> getRoleById(@PathVariable Long id) {
        return rbacService.getRoleByIdWithPermissions(id)
                .map(roleMapper::toResponse)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }
    
    @PutMapping("/{id}")
    @Operation(summary = "Update role")
    public ResponseEntity<RoleResponse> updateRole(@PathVariable Long id, @Valid @RequestBody UpdateRoleRequest request) {
        Role updated = rbacService.updateRole(id, request.getDescription(), request.getIsActive());
        return ResponseEntity.ok(roleMapper.toResponse(updated));
    }
    
    @DeleteMapping("/{id}")
    @Operation(summary = "Delete role")
    public ResponseEntity<Void> deleteRole(@PathVariable Long id) {
        rbacService.deleteRole(id);
        return ResponseEntity.noContent().build();
    }
    
    @PostMapping("/{roleId}/permissions")
    @Operation(summary = "Assign permissions to role")
    public ResponseEntity<Void> assignPermissions(@PathVariable Long roleId, @Valid @RequestBody AssignPermissionsRequest request) {
        rbacService.assignPermissionsToRole(roleId, request.getPermissionIds());
        return ResponseEntity.ok().build();
    }
    
    @DeleteMapping("/{roleId}/permissions/{permissionId}")
    @Operation(summary = "Remove permission from role")
    public ResponseEntity<Void> removePermission(@PathVariable Long roleId, @PathVariable Long permissionId) {
        rbacService.removePermissionFromRole(roleId, permissionId);
        return ResponseEntity.ok().build();
    }
}
