import {
  Controller,
  Get,
  Patch,
  Delete,
  Param,
  Body,
  Query,
  UseGuards,
  Request,
  HttpCode,
  HttpStatus,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiParam } from '@nestjs/swagger';
import { JwtAuthGuard } from '@modules/auth/guards/jwt-auth.guard';
import { AdminGuard } from '../guards/admin.guard';
import { AdminInterventionsService } from '../services/admin-interventions.service';
import {
  ListInterventionsDto,
  AcknowledgeInterventionDto,
  ResolveInterventionDto,
  InterventionAlertDto,
  PaginatedInterventionsDto,
} from '../dto/interventions';

/**
 * AdminInterventionsController
 *
 * @description Controller for managing student intervention alerts in Admin Portal.
 * Allows administrators to view, acknowledge, resolve, and dismiss alerts
 * generated by the system to identify at-risk students.
 *
 * Endpoints:
 * - GET    /admin/interventions          - List all intervention alerts with filters
 * - GET    /admin/interventions/:id      - Get specific alert by ID
 * - PATCH  /admin/interventions/:id/acknowledge - Mark alert as acknowledged
 * - PATCH  /admin/interventions/:id/resolve     - Mark alert as resolved with notes
 * - DELETE /admin/interventions/:id/dismiss     - Dismiss alert (not actionable)
 *
 * Access Control:
 * - All endpoints require authentication (JwtAuthGuard)
 * - All endpoints require admin role (AdminGuard) - SUPER_ADMIN or ADMIN_TEACHER
 * - Full Swagger documentation
 * - Automatic DTO validation via ValidationPipe
 *
 * Integration Points:
 * - Alerts are generated by database function: generate_student_alerts()
 * - Triggered automatically on exercise submissions and progress updates
 * - Alerts feed into teacher dashboards and admin monitoring
 *
 * @see student_intervention_alerts table in progress_tracking schema
 * @see generate_student_alerts() function for alert generation logic
 */
@ApiTags('Admin - Interventions')
@Controller('admin/interventions')
@UseGuards(JwtAuthGuard, AdminGuard)
@ApiBearerAuth()
export class AdminInterventionsController {
  constructor(private readonly interventionsService: AdminInterventionsService) {}

  /**
   * List intervention alerts with filters and pagination
   *
   * Supports filtering by:
   * - severity (low, medium, high, critical)
   * - status (active, acknowledged, resolved, dismissed)
   * - alert_type (no_activity, low_score, declining_trend, etc.)
   * - student_id (specific student)
   * - classroom_id (specific classroom)
   * - date_from / date_to (date range for generated_at)
   * - page / limit (pagination)
   *
   * Results are ordered by:
   * - Severity (critical > high > medium > low)
   * - Then by generated_at DESC (most recent first)
   *
   * Returns student information (name, email) and classroom name joined from related tables.
   */
  @Get()
  @ApiOperation({
    summary: 'List intervention alerts with filters and pagination',
    description:
      'Retrieve student intervention alerts with optional filters by severity, status, type, student, classroom, and date range. Results ordered by severity and generation date.',
  })
  @ApiResponse({
    status: 200,
    description: 'Intervention alerts retrieved successfully',
    type: PaginatedInterventionsDto,
  })
  @ApiResponse({ status: 401, description: 'Unauthorized - Invalid or missing JWT token' })
  @ApiResponse({ status: 403, description: 'Forbidden - Admin role required' })
  async listInterventions(@Query() query: ListInterventionsDto): Promise<PaginatedInterventionsDto> {
    return this.interventionsService.listInterventions(query);
  }

  /**
   * Get a specific intervention alert by ID
   *
   * Returns complete alert information including:
   * - Student details (name, email)
   * - Classroom information (if assigned)
   * - Alert metrics and context
   * - Acknowledgment and resolution history with admin names
   */
  @Get(':id')
  @ApiOperation({
    summary: 'Get intervention alert by ID',
    description:
      'Retrieve detailed information about a specific intervention alert including student data, classroom info, and resolution history.',
  })
  @ApiParam({
    name: 'id',
    description: 'Intervention alert UUID',
    type: String,
    example: '123e4567-e89b-12d3-a456-426614174000',
  })
  @ApiResponse({
    status: 200,
    description: 'Intervention alert retrieved successfully',
    type: InterventionAlertDto,
  })
  @ApiResponse({ status: 404, description: 'Intervention alert not found' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden - Admin role required' })
  async getInterventionById(@Param('id') id: string): Promise<InterventionAlertDto> {
    return this.interventionsService.getInterventionById(id);
  }

  /**
   * Acknowledge an intervention alert
   *
   * Changes status from 'active' to 'acknowledged', indicating an administrator
   * is aware of the alert and is taking action or monitoring the situation.
   *
   * Can only be applied to alerts in 'active' status.
   *
   * Records:
   * - acknowledged_by (admin user ID)
   * - acknowledged_at (timestamp)
   * - Optional acknowledgment note
   */
  @Patch(':id/acknowledge')
  @ApiOperation({
    summary: 'Acknowledge intervention alert',
    description:
      "Change alert status from 'active' to 'acknowledged'. Indicates admin is aware and handling the intervention.",
  })
  @ApiParam({
    name: 'id',
    description: 'Intervention alert UUID',
    type: String,
    example: '123e4567-e89b-12d3-a456-426614174000',
  })
  @ApiResponse({
    status: 200,
    description: 'Intervention alert acknowledged successfully',
    type: InterventionAlertDto,
  })
  @ApiResponse({ status: 400, description: "Alert is not in 'active' status" })
  @ApiResponse({ status: 404, description: 'Intervention alert not found' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden - Admin role required' })
  async acknowledgeIntervention(
    @Param('id') id: string,
      @Body() dto: AcknowledgeInterventionDto,
      @Request() req: any,
  ): Promise<InterventionAlertDto> {
    const userId = req.user?.id || req.user?.sub;
    return this.interventionsService.acknowledgeIntervention(id, dto.acknowledgment_note, userId);
  }

  /**
   * Resolve an intervention alert
   *
   * Changes status to 'resolved', indicating the issue has been addressed
   * and intervention actions have been taken.
   *
   * Requires:
   * - Resolution notes (minimum 10 characters) explaining actions taken
   * - Alert must be in 'active' or 'acknowledged' status
   *
   * Records:
   * - resolved_by (admin user ID)
   * - resolved_at (timestamp)
   * - resolution_notes (required)
   */
  @Patch(':id/resolve')
  @ApiOperation({
    summary: 'Resolve intervention alert',
    description:
      "Mark alert as resolved with required resolution notes. Can only be applied to 'active' or 'acknowledged' alerts.",
  })
  @ApiParam({
    name: 'id',
    description: 'Intervention alert UUID',
    type: String,
    example: '123e4567-e89b-12d3-a456-426614174000',
  })
  @ApiResponse({
    status: 200,
    description: 'Intervention alert resolved successfully',
    type: InterventionAlertDto,
  })
  @ApiResponse({
    status: 400,
    description: 'Alert cannot be resolved in current status or invalid resolution notes',
  })
  @ApiResponse({ status: 404, description: 'Intervention alert not found' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden - Admin role required' })
  async resolveIntervention(
    @Param('id') id: string,
      @Body() dto: ResolveInterventionDto,
      @Request() req: any,
  ): Promise<InterventionAlertDto> {
    const userId = req.user?.id || req.user?.sub;
    return this.interventionsService.resolveIntervention(id, dto.resolution_notes, userId);
  }

  /**
   * Dismiss an intervention alert
   *
   * Changes status to 'dismissed', indicating the alert does not require action.
   * Use for false positives or alerts that are not relevant/actionable.
   *
   * Unlike resolve, dismiss does not require notes and indicates the alert
   * was not acted upon (rather than completed).
   *
   * Can be applied to alerts in any status.
   */
  @Delete(':id/dismiss')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({
    summary: 'Dismiss intervention alert',
    description:
      "Mark alert as dismissed. Use for false positives or non-actionable alerts that don't require intervention.",
  })
  @ApiParam({
    name: 'id',
    description: 'Intervention alert UUID',
    type: String,
    example: '123e4567-e89b-12d3-a456-426614174000',
  })
  @ApiResponse({
    status: 200,
    description: 'Intervention alert dismissed successfully',
    type: InterventionAlertDto,
  })
  @ApiResponse({ status: 404, description: 'Intervention alert not found' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden - Admin role required' })
  async dismissIntervention(@Param('id') id: string): Promise<InterventionAlertDto> {
    return this.interventionsService.dismissIntervention(id);
  }
}
