import {
  Body,
  Controller,
  Get,
  Post,
  Put,
  Patch,
  Delete,
  Param,
  Query,
  Req,
  UseGuards,
  HttpCode,
  HttpStatus,
  Headers,
} from '@nestjs/common';
import { SamlSsoService } from './saml-sso.service';
import { ScimProvisioningService } from './scim-provisioning.service';
import { DlpService } from './dlp.service';
import { CustomRolesService } from './custom-roles.service';
import { InformationBarriersService } from './information-barriers.service';
import { JwtAuthGuard } from '../../common/guards/jwt.guard';
import { CurrentUser } from '../../common/decorators/current-user.decorator';
import { Workspace } from '../../common/decorators/workspace.decorator';

/**
 * FASE 6 — Enterprise Security Controller
 *
 * Agrupa todos los endpoints de seguridad enterprise:
 * - SAML SSO
 * - SCIM Provisioning
 * - DLP (Data Loss Prevention)
 * - Custom Roles
 * - Information Barriers
 */
@Controller()
export class EnterpriseController {
  constructor(
    private readonly samlSsoService: SamlSsoService,
    private readonly scimProvisioningService: ScimProvisioningService,
    private readonly dlpService: DlpService,
    private readonly customRolesService: CustomRolesService,
    private readonly informationBarriersService: InformationBarriersService,
  ) {}

  // ============ SAML SSO ============

  @Get('enterprise/saml/config')
  @UseGuards(JwtAuthGuard)
  async getSamlConfig(@Workspace('id') wsId: string) {
    return this.samlSsoService.getConfig(wsId);
  }

  @Post('enterprise/saml/config')
  @UseGuards(JwtAuthGuard)
  async configureSaml(
    @Workspace('id') wsId: string,
    @CurrentUser('userId') userId: string,
    @Body() dto: any,
  ) {
    return this.samlSsoService.configure(wsId, userId, dto);
  }

  @Post('enterprise/saml/toggle')
  @UseGuards(JwtAuthGuard)
  async toggleSaml(
    @Workspace('id') wsId: string,
    @Body() dto: { active: boolean },
  ) {
    return this.samlSsoService.toggle(wsId, dto.active);
  }

  @Delete('enterprise/saml/config')
  @UseGuards(JwtAuthGuard)
  async deleteSaml(@Workspace('id') wsId: string) {
    return this.samlSsoService.delete(wsId);
  }

  @Get('enterprise/saml/initiate')
  @UseGuards(JwtAuthGuard)
  async initiateSso(@Workspace('id') wsId: string) {
    return this.samlSsoService.initiateSso(wsId);
  }

  @Get('enterprise/saml/metadata')
  async getSamlMetadata(@Query('workspace_id') wsId: string) {
    return this.samlSsoService.getServiceProviderMetadata(wsId);
  }

  @Post('enterprise/saml/acs')
  @HttpCode(HttpStatus.OK)
  async samlAcsCallback(
    @Body() dto: { SAMLResponse: string; RelayState: string },
  ) {
    return this.samlSsoService.handleAcsCallback(dto.SAMLResponse, dto.RelayState);
  }

  // ============ SCIM Provisioning ============

  @Get('enterprise/scim/tokens')
  @UseGuards(JwtAuthGuard)
  async listScimTokens(@Workspace('id') wsId: string) {
    return this.scimProvisioningService.listTokens(wsId);
  }

  @Post('enterprise/scim/tokens')
  @UseGuards(JwtAuthGuard)
  async createScimToken(
    @Workspace('id') wsId: string,
    @CurrentUser('userId') userId: string,
    @Body() dto: { name: string },
  ) {
    return this.scimProvisioningService.createToken(wsId, userId, dto.name);
  }

  @Delete('enterprise/scim/tokens/:tokenId')
  @UseGuards(JwtAuthGuard)
  async revokeScimToken(
    @Workspace('id') wsId: string,
    @Param('tokenId') tokenId: string,
  ) {
    return this.scimProvisioningService.revokeToken(wsId, tokenId);
  }

  // --- SCIM API endpoints (token auth) ---

  @Get('scim/v2/Users')
  async scimListUsers(
    @Headers('authorization') auth: string,
    @Query('count') count?: number,
    @Query('startIndex') startIndex?: number,
    @Query('filter') filter?: string,
  ) {
    const wsId = await this.scimProvisioningService.validateToken(auth.replace('Bearer ', ''));
    return this.scimProvisioningService.listUsers(wsId, { count, startIndex, filter });
  }

  @Get('scim/v2/Users/:userId')
  async scimGetUser(
    @Headers('authorization') auth: string,
    @Param('userId') userId: string,
  ) {
    const wsId = await this.scimProvisioningService.validateToken(auth.replace('Bearer ', ''));
    return this.scimProvisioningService.getUser(wsId, userId);
  }

  @Post('scim/v2/Users')
  @HttpCode(HttpStatus.CREATED)
  async scimCreateUser(
    @Headers('authorization') auth: string,
    @Body() body: any,
  ) {
    const wsId = await this.scimProvisioningService.validateToken(auth.replace('Bearer ', ''));
    return this.scimProvisioningService.createUser(wsId, body);
  }

  @Put('scim/v2/Users/:userId')
  async scimUpdateUser(
    @Headers('authorization') auth: string,
    @Param('userId') userId: string,
    @Body() body: any,
  ) {
    const wsId = await this.scimProvisioningService.validateToken(auth.replace('Bearer ', ''));
    return this.scimProvisioningService.updateUser(wsId, userId, body);
  }

  @Patch('scim/v2/Users/:userId')
  async scimPatchUser(
    @Headers('authorization') auth: string,
    @Param('userId') userId: string,
    @Body() body: { Operations: any[] } | any[],
  ) {
    const wsId = await this.scimProvisioningService.validateToken(auth.replace('Bearer ', ''));
    const operations = Array.isArray(body) ? body : body.Operations;
    return this.scimProvisioningService.patchUser(wsId, userId, operations);
  }

  @Delete('scim/v2/Users/:userId')
  async scimDeleteUser(
    @Headers('authorization') auth: string,
    @Param('userId') userId: string,
  ) {
    const wsId = await this.scimProvisioningService.validateToken(auth.replace('Bearer ', ''));
    return this.scimProvisioningService.deleteUser(wsId, userId);
  }

  @Get('scim/v2/Groups')
  async scimListGroups(@Headers('authorization') auth: string) {
    const wsId = await this.scimProvisioningService.validateToken(auth.replace('Bearer ', ''));
    return this.scimProvisioningService.listGroups(wsId);
  }

  // ============ DLP ============

  @Get('enterprise/dlp/rules')
  @UseGuards(JwtAuthGuard)
  async listDlpRules(@Workspace('id') wsId: string) {
    return this.dlpService.listRules(wsId);
  }

  @Post('enterprise/dlp/rules')
  @UseGuards(JwtAuthGuard)
  async createDlpRule(
    @Workspace('id') wsId: string,
    @CurrentUser('userId') userId: string,
    @Body() dto: any,
  ) {
    return this.dlpService.createRule(wsId, userId, dto);
  }

  @Put('enterprise/dlp/rules/:ruleId')
  @UseGuards(JwtAuthGuard)
  async updateDlpRule(
    @Workspace('id') wsId: string,
    @Param('ruleId') ruleId: string,
    @Body() dto: any,
  ) {
    return this.dlpService.updateRule(wsId, ruleId, dto);
  }

  @Delete('enterprise/dlp/rules/:ruleId')
  @UseGuards(JwtAuthGuard)
  async deleteDlpRule(
    @Workspace('id') wsId: string,
    @Param('ruleId') ruleId: string,
  ) {
    return this.dlpService.deleteRule(wsId, ruleId);
  }

  @Get('enterprise/dlp/violations')
  @UseGuards(JwtAuthGuard)
  async listDlpViolations(
    @Workspace('id') wsId: string,
    @Query() query: any,
  ) {
    return this.dlpService.listViolations(wsId, {
      page: parseInt(query.page),
      limit: parseInt(query.limit),
      ruleId: query.rule_id,
    });
  }

  @Post('enterprise/dlp/scan/:channelId')
  @UseGuards(JwtAuthGuard)
  async scanChannel(
    @Workspace('id') wsId: string,
    @Param('channelId') channelId: string,
    @Body() dto: { limit?: number },
  ) {
    return this.dlpService.scanChannel(wsId, channelId, dto);
  }

  @Get('enterprise/dlp/patterns')
  @UseGuards(JwtAuthGuard)
  async getPredefinedPatterns() {
    return this.dlpService.getPredefinedPatterns();
  }

  // ============ Custom Roles ============

  @Get('enterprise/roles')
  @UseGuards(JwtAuthGuard)
  async listRoles(@Workspace('id') wsId: string) {
    return this.customRolesService.list(wsId);
  }

  @Get('enterprise/roles/permissions')
  @UseGuards(JwtAuthGuard)
  async listPermissions() {
    return this.customRolesService.getAvailablePermissions();
  }

  @Get('enterprise/roles/:roleId')
  @UseGuards(JwtAuthGuard)
  async getRole(
    @Workspace('id') wsId: string,
    @Param('roleId') roleId: string,
  ) {
    return this.customRolesService.get(wsId, roleId);
  }

  @Post('enterprise/roles')
  @UseGuards(JwtAuthGuard)
  async createRole(
    @Workspace('id') wsId: string,
    @CurrentUser('userId') userId: string,
    @Body() dto: any,
  ) {
    return this.customRolesService.create(wsId, userId, dto);
  }

  @Put('enterprise/roles/:roleId')
  @UseGuards(JwtAuthGuard)
  async updateRole(
    @Workspace('id') wsId: string,
    @Param('roleId') roleId: string,
    @Body() dto: any,
  ) {
    return this.customRolesService.update(wsId, roleId, dto);
  }

  @Delete('enterprise/roles/:roleId')
  @UseGuards(JwtAuthGuard)
  async deleteRole(
    @Workspace('id') wsId: string,
    @Param('roleId') roleId: string,
  ) {
    return this.customRolesService.delete(wsId, roleId);
  }

  @Post('enterprise/roles/:roleId/assign/:memberId')
  @UseGuards(JwtAuthGuard)
  async assignRole(
    @Workspace('id') wsId: string,
    @Param('roleId') roleId: string,
    @Param('memberId') memberId: string,
  ) {
    return this.customRolesService.assignToMember(wsId, roleId, memberId);
  }

  // ============ Information Barriers ============

  @Get('enterprise/barriers')
  @UseGuards(JwtAuthGuard)
  async listBarriers(@Workspace('id') wsId: string) {
    return this.informationBarriersService.list(wsId);
  }

  @Get('enterprise/barriers/:barrierId')
  @UseGuards(JwtAuthGuard)
  async getBarrier(
    @Workspace('id') wsId: string,
    @Param('barrierId') barrierId: string,
  ) {
    return this.informationBarriersService.get(wsId, barrierId);
  }

  @Post('enterprise/barriers')
  @UseGuards(JwtAuthGuard)
  async createBarrier(
    @Workspace('id') wsId: string,
    @CurrentUser('userId') userId: string,
    @Body() dto: any,
  ) {
    return this.informationBarriersService.create(wsId, userId, dto);
  }

  @Put('enterprise/barriers/:barrierId')
  @UseGuards(JwtAuthGuard)
  async updateBarrier(
    @Workspace('id') wsId: string,
    @Param('barrierId') barrierId: string,
    @Body() dto: any,
  ) {
    return this.informationBarriersService.update(wsId, barrierId, dto);
  }

  @Post('enterprise/barriers/:barrierId/toggle')
  @UseGuards(JwtAuthGuard)
  async toggleBarrier(
    @Workspace('id') wsId: string,
    @Param('barrierId') barrierId: string,
    @Body() dto: { active: boolean },
  ) {
    return this.informationBarriersService.toggle(wsId, barrierId, dto.active);
  }

  @Delete('enterprise/barriers/:barrierId')
  @UseGuards(JwtAuthGuard)
  async deleteBarrier(
    @Workspace('id') wsId: string,
    @Param('barrierId') barrierId: string,
  ) {
    return this.informationBarriersService.delete(wsId, barrierId);
  }

  @Post('enterprise/barriers/check')
  @UseGuards(JwtAuthGuard)
  async checkBarrier(
    @Workspace('id') wsId: string,
    @Body() dto: { user_a: string; user_b: string },
  ) {
    return this.informationBarriersService.checkBarrier(wsId, dto.user_a, dto.user_b);
  }
}