import {
  Controller,
  Post,
  Get,
  Patch,
  Delete,
  Body,
  Param,
  Query,
  UseGuards,
  HttpCode,
  HttpStatus,
  Logger,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiParam,
  ApiQuery,
  ApiSecurity,
} from '@nestjs/swagger';
import { AuthGuard } from '@nestjs/passport';
import { WebhooksService } from './services/webhooks.service';
import {
  CreateWebhookDto,
  UpdateWebhookDto,
  WebhookResponseDto,
  WebhookTestResultDto,
} from './dto';
import { PaginationDto } from '../../common/dto/pagination.dto';

@ApiTags('Webhooks')
@Controller('webhooks')
@ApiBearerAuth('BearerAuth')
@UseGuards(AuthGuard('jwt'))
export class WebhooksController {
  private readonly logger = new Logger(WebhooksController.name);

  constructor(private readonly webhooksService: WebhooksService) {}

  @Get()
  @ApiOperation({
    summary: 'List all webhooks',
    description: 'Get all webhook subscriptions with pagination',
  })
  @ApiQuery({
    name: 'page',
    required: false,
    type: Number,
    description: 'Page number (default: 1)',
  })
  @ApiQuery({
    name: 'limit',
    required: false,
    type: Number,
    description: 'Items per page (default: 20)',
  })
  @ApiResponse({
    status: 200,
    description: 'Paginated list of all webhooks',
  })
  async findAllWebhooks(@Query() pagination: PaginationDto) {
    return this.webhooksService.findAllPaginated(pagination);
  }

  @Post(':departmentId')
  @HttpCode(HttpStatus.CREATED)
  @ApiOperation({
    summary: 'Register webhook',
    description: 'Register a new webhook endpoint for a department to receive event notifications',
  })
  @ApiParam({ name: 'departmentId', description: 'Department ID (UUID)' })
  @ApiResponse({
    status: 201,
    description: 'Webhook registered successfully',
    type: WebhookResponseDto,
  })
  @ApiResponse({ status: 400, description: 'Invalid webhook data' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  async register(@Param('departmentId') departmentId: string, @Body() dto: CreateWebhookDto) {
    this.logger.debug(`Registering webhook for department: ${departmentId}`);
    return this.webhooksService.register(departmentId, dto);
  }

  @Get('department/:departmentId')
  @ApiOperation({
    summary: 'List webhooks for department',
    description: 'Get all webhook subscriptions for a specific department',
  })
  @ApiParam({ name: 'departmentId', description: 'Department ID (UUID)' })
  @ApiResponse({
    status: 200,
    description: 'List of webhooks',
    type: [WebhookResponseDto],
  })
  async findAll(@Param('departmentId') departmentId: string) {
    return this.webhooksService.findAll(departmentId);
  }

  @Get(':id')
  @ApiOperation({
    summary: 'Get webhook by ID',
    description: 'Get details of a specific webhook subscription',
  })
  @ApiParam({ name: 'id', description: 'Webhook ID (UUID)' })
  @ApiResponse({
    status: 200,
    description: 'Webhook details',
    type: WebhookResponseDto,
  })
  @ApiResponse({ status: 404, description: 'Webhook not found' })
  async findById(@Param('id') id: string) {
    return this.webhooksService.findById(id);
  }

  @Patch(':id')
  @ApiOperation({
    summary: 'Update webhook',
    description: 'Update webhook URL, events, or active status',
  })
  @ApiParam({ name: 'id', description: 'Webhook ID (UUID)' })
  @ApiResponse({
    status: 200,
    description: 'Webhook updated successfully',
    type: WebhookResponseDto,
  })
  @ApiResponse({ status: 404, description: 'Webhook not found' })
  async update(@Param('id') id: string, @Body() dto: UpdateWebhookDto) {
    this.logger.debug(`Updating webhook: ${id}`);
    return this.webhooksService.update(id, dto);
  }

  @Delete(':id')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({
    summary: 'Delete webhook',
    description: 'Remove a webhook subscription',
  })
  @ApiParam({ name: 'id', description: 'Webhook ID (UUID)' })
  @ApiResponse({ status: 204, description: 'Webhook deleted successfully' })
  @ApiResponse({ status: 404, description: 'Webhook not found' })
  async delete(@Param('id') id: string) {
    this.logger.debug(`Deleting webhook: ${id}`);
    await this.webhooksService.delete(id);
  }

  @Post(':id/test')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({
    summary: 'Test webhook',
    description: 'Send a test event to the webhook endpoint to verify connectivity',
  })
  @ApiParam({ name: 'id', description: 'Webhook ID (UUID)' })
  @ApiResponse({
    status: 200,
    description: 'Webhook test result',
    type: WebhookTestResultDto,
  })
  @ApiResponse({ status: 404, description: 'Webhook not found' })
  async test(@Param('id') id: string) {
    this.logger.debug(`Testing webhook: ${id}`);
    return this.webhooksService.test(id);
  }

  @Get(':id/logs')
  @ApiOperation({
    summary: 'Get webhook delivery logs',
    description: 'Get paginated delivery logs for a specific webhook',
  })
  @ApiParam({ name: 'id', description: 'Webhook ID (UUID)' })
  @ApiQuery({
    name: 'page',
    required: false,
    type: Number,
    description: 'Page number (default: 1)',
  })
  @ApiQuery({
    name: 'limit',
    required: false,
    type: Number,
    description: 'Items per page (default: 20)',
  })
  @ApiResponse({ status: 200, description: 'Webhook delivery logs' })
  @ApiResponse({ status: 404, description: 'Webhook not found' })
  async getLogs(@Param('id') id: string, @Query() pagination: PaginationDto) {
    return this.webhooksService.getLogs(id, pagination);
  }
}
