import {
  Controller,
  Post,
  Body,
  Headers,
  UseGuards,
  Get,
  Param,
  Query,
  Res,
  ParseIntPipe,
} from '@nestjs/common';
import { MigrationService } from './migration.service';
import { ImportCorrespondenceDto } from './dto/import-correspondence.dto';
import { EnqueueMigrationDto } from './dto/enqueue-migration.dto';
import { CommitBatchDto } from './dto/commit-batch.dto';
import { CreateMigrationErrorDto } from './dto/create-migration-error.dto';
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
import { CurrentUser } from '../../common/decorators/current-user.decorator';
import { User } from '../user/entities/user.entity';
import {
  ApiTags,
  ApiOperation,
  ApiBearerAuth,
  ApiHeader,
  ApiQuery,
  ApiParam,
} from '@nestjs/swagger';
import { MigrationQueueQueryDto } from './dto/migration-queue-query.dto';
import type { Response } from 'express';

@ApiTags('Migration')
@ApiBearerAuth()
@Controller('migration')
export class MigrationController {
  constructor(private readonly migrationService: MigrationService) {}

  @Post('import')
  @UseGuards(JwtAuthGuard)
  @ApiOperation({
    summary: 'Import generic legacy correspondence record via n8n integration',
  })
  @ApiHeader({
    name: 'Idempotency-Key',
    description:
      'Unique key per document and batch to prevent duplicate inserts',
    required: true,
  })
  async importCorrespondence(
    @Body() dto: ImportCorrespondenceDto,
    @Headers('idempotency-key') idempotencyKey: string,
    @CurrentUser() user: User
  ) {
    const userId = user?.user_id || 5;
    return this.migrationService.importCorrespondence(
      dto,
      idempotencyKey,
      userId
    );
  }

  @Post('commit_batch')
  @UseGuards(JwtAuthGuard)
  @ApiOperation({
    summary: 'Batch approve and import migration review queue items',
  })
  @ApiHeader({
    name: 'Idempotency-Key',
    description:
      'Unique key for the entire batch to prevent duplicate execution',
    required: true,
  })
  async commitBatch(
    @Body() dto: CommitBatchDto,
    @Headers('idempotency-key') idempotencyKey: string,
    @CurrentUser() user: User
  ) {
    const userId = user?.user_id || 5;
    return this.migrationService.commitBatch(dto, idempotencyKey, userId);
  }

  @Post('queue')
  @UseGuards(JwtAuthGuard)
  @ApiOperation({
    summary: 'Enqueue a record into the staging migration review queue',
  })
  async enqueueRecord(@Body() dto: EnqueueMigrationDto) {
    return this.migrationService.enqueueRecord(dto);
  }

  @Get('queue')
  @UseGuards(JwtAuthGuard)
  @ApiOperation({ summary: 'Get migration review queue' })
  async getReviewQueue(@Query() query: MigrationQueueQueryDto) {
    return this.migrationService.getReviewQueue(query);
  }

  @Get('queue/:id')
  @UseGuards(JwtAuthGuard)
  @ApiOperation({ summary: 'Get a specific queue item by ID' })
  @ApiParam({ name: 'id', type: Number })
  async getQueueItemById(@Param('id', ParseIntPipe) id: number) {
    return this.migrationService.getQueueItemById(id);
  }

  @Post('errors')
  @UseGuards(JwtAuthGuard)
  @ApiOperation({ summary: 'Log a migration error from n8n workflow' })
  async createError(@Body() dto: CreateMigrationErrorDto) {
    return this.migrationService.createError(dto);
  }

  @Get('errors')
  @UseGuards(JwtAuthGuard)
  @ApiOperation({ summary: 'Get migration errors' })
  @ApiQuery({ name: 'page', required: false, type: Number })
  @ApiQuery({ name: 'limit', required: false, type: Number })
  async getErrors(
    @Query('page') page?: number,
    @Query('limit') limit?: number
  ) {
    return this.migrationService.getErrors(page, limit);
  }

  @Post('queue/:id/approve')
  @UseGuards(JwtAuthGuard)
  @ApiOperation({ summary: 'Approve and import a queued migration item' })
  @ApiParam({ name: 'id', type: Number })
  @ApiHeader({
    name: 'Idempotency-Key',
    description:
      'Unique key per document and batch to prevent duplicate inserts',
    required: true,
  })
  async approveQueueItem(
    @Param('id', ParseIntPipe) id: number,
    @Body() dto: ImportCorrespondenceDto,
    @Headers('idempotency-key') idempotencyKey: string,
    @CurrentUser() user: User
  ) {
    const userId = user?.user_id || 5;
    return this.migrationService.approveQueueItem(
      id,
      dto,
      idempotencyKey,
      userId
    );
  }

  @Post('queue/:id/reject')
  @UseGuards(JwtAuthGuard)
  @ApiOperation({ summary: 'Reject a queued migration item' })
  @ApiParam({ name: 'id', type: Number })
  async rejectQueueItem(
    @Param('id', ParseIntPipe) id: number,
    @CurrentUser() user: User
  ) {
    const userId = user?.user_id || 5;
    return this.migrationService.rejectQueueItem(id, userId);
  }

  @Get('staging-file')
  @UseGuards(JwtAuthGuard)
  @ApiOperation({ summary: 'Stream a file from staging' })
  @ApiQuery({ name: 'path', required: true, type: String })
  getStagingFile(@Query('path') filePath: string, @Res() res: Response) {
    const stream = this.migrationService.getStagingFileStream(filePath);
    res.set({
      'Content-Type': 'application/pdf',
      'Content-Disposition': 'inline; filename="document.pdf"',
    });
    stream.pipe(res);
  }
}
