import {
  Controller,
  Post,
  Get,
  Body,
  Query,
  HttpCode,
  HttpStatus,
  Param,
  UsePipes,
  ValidationPipe,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBody, ApiQuery, ApiParam } from '@nestjs/swagger';
import { TwilioWebhookService } from './twilio-webhook.service';
import { TwilioWebhookEventDto } from './dto/webhook-event.dto';
import { TwilioSmsEventType } from './entities/twilio-webhook-event.entity';
import { TwilioWebhookEvent } from './entities/twilio-webhook-event.entity';

@ApiTags('Twilio Webhook')
@Controller('twilio-webhook')
export class TwilioWebhookController {
  constructor(
    private readonly twilioWebhookService: TwilioWebhookService,
  ) {}

  @Post('receive')
  @HttpCode(HttpStatus.OK)
  @UsePipes(new ValidationPipe({ whitelist: false, forbidNonWhitelisted: false }))
  @ApiOperation({ summary: 'Receive webhook events from Twilio' })
  @ApiBody({ 
    type: TwilioWebhookEventDto,
    description: 'Twilio sends data as application/x-www-form-urlencoded',
  })
  @ApiResponse({
    status: 200,
    description: 'Webhook event received and processed successfully',
  })
  @ApiResponse({
    status: 400,
    description: 'Bad request - invalid webhook data',
  })
  async receiveWebhook(@Body() eventData: TwilioWebhookEventDto | Record<string, unknown>) {
    // Twilio envoie les données en format application/x-www-form-urlencoded
    // NestJS les parse automatiquement en objet
    const processedEvent = await this.twilioWebhookService.processWebhookEvent(eventData);
    return { processed: 1, event: processedEvent };
  }

  @Get('events')
  @ApiOperation({ summary: 'Get all webhook events' })
  @ApiQuery({ name: 'limit', required: false, type: Number, description: 'Number of events to return', example: 100 })
  @ApiQuery({ name: 'offset', required: false, type: Number, description: 'Offset for pagination', example: 0 })
  @ApiResponse({
    status: 200,
    description: 'Events retrieved successfully',
  })
  async getAllEvents(
    @Query('limit') limit?: string,
    @Query('offset') offset?: string,
  ) {
    const limitNum = limit ? parseInt(limit, 10) : 100;
    const offsetNum = offset ? parseInt(offset, 10) : 0;
    return await this.twilioWebhookService.getAllEvents(limitNum, offsetNum);
  }

  @Get('events/message/:messageSid')
  @ApiOperation({ summary: 'Get all events for a specific message SID' })
  @ApiParam({ name: 'messageSid', description: 'Message SID from Twilio' })
  @ApiResponse({
    status: 200,
    description: 'Events for message retrieved successfully',
  })
  async getEventsByMessageSid(@Param('messageSid') messageSid: string) {
    return await this.twilioWebhookService.getEventsByMessageSid(messageSid);
  }

  @Get('events/type/:eventType')
  @ApiOperation({ summary: 'Get events by event type' })
  @ApiParam({ 
    name: 'eventType', 
    description: 'Event type',
    enum: TwilioSmsEventType,
  })
  @ApiQuery({ name: 'limit', required: false, type: Number, description: 'Number of events to return', example: 100 })
  @ApiResponse({
    status: 200,
    description: 'Events by type retrieved successfully',
  })
  async getEventsByType(
    @Param('eventType') eventType: TwilioSmsEventType,
    @Query('limit') limit?: string,
  ) {
    const limitNum = limit ? parseInt(limit, 10) : 100;
    return await this.twilioWebhookService.getEventsByType(eventType, limitNum);
  }

  @Get('events/phone/:phoneNumber')
  @ApiOperation({ summary: 'Get events by phone number' })
  @ApiParam({ name: 'phoneNumber', description: 'Phone number' })
  @ApiQuery({ name: 'limit', required: false, type: Number, description: 'Number of events to return', example: 100 })
  @ApiResponse({
    status: 200,
    description: 'Events for phone number retrieved successfully',
  })
  async getEventsByPhoneNumber(
    @Param('phoneNumber') phoneNumber: string,
    @Query('limit') limit?: string,
  ) {
    const limitNum = limit ? parseInt(limit, 10) : 100;
    return await this.twilioWebhookService.getEventsByPhoneNumber(phoneNumber, limitNum);
  }
}

