import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  Query,
  UseGuards,
  ParseUUIDPipe,
  HttpCode,
  BadRequestException,
} from '@nestjs/common';
import { WorkflowRolesService } from './workflow-roles.service';
import {
  CreateWorkflowRoleDto,
  UpdateWorkflowRoleDto,
  AssignWorkflowRoleUsersDto,
  WorkflowRoleQueryDto,
  ResolveWorkflowRoleDto,
} from './dto/workflow-role.dto';
import { PermissionsGuard } from '../auth/guards/permissions.guard';
import { RequirePermissions } from '@common/decorators/permissions.decorator';
import { InternalServiceGuard } from '../guards/internal-service.guard';
import { Public } from '../../../common/decorators/public.decorator';
import { Auditable, Sensitive, Financial } from '@core/observability/audit/decorators/auditable.decorator';

@Controller('workflow-roles')
export class WorkflowRolesController {
  constructor(private readonly workflowRolesService: WorkflowRolesService) {}

  /**
   * Get workflow role list
   * Scope: organization - 只能查看本组织工作流角色
   */
  @Get()
  @RequirePermissions('role:read')
  async findAll(@Query() query: WorkflowRoleQueryDto) {
    return this.workflowRolesService.findAll(query);
  }

  /**
   * Get workflow role by ID
   * Scope: organization - 只能查看本组织工作流角色
   */
  @Get(':id')
  @RequirePermissions('role:read')
  async findOne(@Param('id', ParseUUIDPipe) id: string) {
    return this.workflowRolesService.findOne(id);
  }

  /**
   * Create workflow role
   * Scope: organization - 只能在本组织创建工作流角色
   */
  @Post()
  @Auditable()
  @Sensitive()
  @RequirePermissions('role:create')
  async create(@Body() createDto: CreateWorkflowRoleDto) {
    return this.workflowRolesService.create(createDto);
  }

  /**
   * Update workflow role
   * Scope: organization - 只能更新本组织工作流角色
   */
  @Put(':id')
  @Auditable()
  @Sensitive()
  @RequirePermissions('role:update')
  async update(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() updateDto: UpdateWorkflowRoleDto & { code?: string },  // 接受 code 但会拒绝
  ) {
    // 检查是否尝试修改 code
    if ('code' in updateDto && updateDto.code !== undefined) {
      throw new BadRequestException('流程角色代码不可修改');
    }
    return this.workflowRolesService.update(id, updateDto);
  }

  /**
   * Delete workflow role
   * Scope: organization - 只能删除本组织工作流角色
   */
  @Delete(':id')
  @Auditable()
  @Sensitive()
  @RequirePermissions('role:delete')
  async remove(@Param('id', ParseUUIDPipe) id: string) {
    return this.workflowRolesService.remove(id);
  }

  /**
   * Get workflow role users
   * Scope: organization - 只能查看本组织工作流角色用户
   */
  @Get(':id/users')
  @RequirePermissions('role:read')
  async getUsers(@Param('id', ParseUUIDPipe) id: string) {
    return this.workflowRolesService.getUsers(id);
  }

  /**
   * Assign users to workflow role
   * Scope: organization - 只能在本组织分配工作流角色
   */
  @Post(':id/users')
  @HttpCode(200)  // 关联操作返回 200，而非 201
  @Auditable()
  @Sensitive()
  @RequirePermissions('role:manage')
  async assignUsers(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() assignUsersDto: AssignWorkflowRoleUsersDto,
  ) {
    return this.workflowRolesService.assignUsers(id, assignUsersDto.userIds);
  }

  /**
   * Remove user from workflow role
   * Scope: organization - 只能在本组织移除工作流角色
   */
  @Delete(':id/users/:userId')
  @Auditable()
  @Sensitive()
  @RequirePermissions('role:manage')
  async removeUser(
    @Param('id', ParseUUIDPipe) id: string,
    @Param('userId', ParseUUIDPipe) userId: string,
  ) {
    return this.workflowRolesService.removeUser(id, userId);
  }

  /**
   * Resolve workflow role to actual users
   * Called by approval engine and other internal services
   * Protected by InternalServiceGuard for service-to-service auth
   */
  @Post('resolve')
  @Auditable()
  @Sensitive()
  @HttpCode(200)
  @Public()
  @UseGuards(InternalServiceGuard)
  async resolve(@Body() resolveDto: ResolveWorkflowRoleDto) {
    return this.workflowRolesService.resolve(resolveDto);
  }
}

