import { Controller, Get, HttpException, HttpStatus, Param, Res, StreamableFile, Header } from '@nestjs/common';
import { Response } from 'express';
import { BackupService } from './backup.service';
import { Public } from 'src/auth/public.decorator';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';

@ApiTags('Backup')
@Controller('backup')
export class BackupController {
  constructor(private readonly backupService: BackupService) {}

  /**
   * Create database backup and automatically download the file
   * No authentication required
   */
  @Public()
  @Get('create')
  @Header('Content-Type', 'application/gzip')
  @ApiOperation({ summary: 'Create database backup and automatically download the file' })
  @ApiResponse({ status: 200, description: 'Backup file download started automatically' })
  @ApiResponse({ status: 500, description: 'Internal server error' })
  async createBackup(@Res({ passthrough: true }) res: Response) {
    try {
      // Create the backup and get file info
      const backupInfo = await this.backupService.createBackupForDownload();

      // Set response headers for file download
      res.set({
        'Content-Type': 'application/gzip',
        'Content-Disposition': `attachment; filename="${backupInfo.fileName}"`,
        'Content-Length': backupInfo.size.toString(),
        'X-Backup-Info': JSON.stringify({
          database: backupInfo.database,
          size: backupInfo.size,
          created_at: backupInfo.createdAt,
          expires_in: '24 hours'
        })
      });

      // Stream the file directly
      const file = require('fs').createReadStream(backupInfo.filePath);
      return new StreamableFile(file);

    } catch (error) {
      throw new HttpException(
        {
          success: false,
          message: 'Failed to create database backup',
          error: error.message,
        },
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  /**
   * Download a specific backup file
   * Files are automatically deleted after 24 hours
   */
  @Public()
  @Get('download/:fileName')
  @ApiOperation({ summary: 'Download a specific backup file' })
  @ApiResponse({ status: 200, description: 'File download started' })
  @ApiResponse({ status: 404, description: 'Backup file not found' })
  @ApiResponse({ status: 400, description: 'Invalid backup file or expired' })
  async downloadBackup(
    @Param('fileName') fileName: string,
    @Res({ passthrough: true }) res: Response,
  ) {
    try {
      const { filePath, fileName: actualFileName, size } = await this.backupService.downloadBackup(fileName);

      // Set response headers for file download
      res.set({
        'Content-Type': 'application/gzip',
        'Content-Disposition': `attachment; filename="${actualFileName}"`,
        'Content-Length': size.toString(),
      });

      // Stream the file
      const file = require('fs').createReadStream(filePath);
      return new StreamableFile(file);

    } catch (error) {
      throw new HttpException(
        {
          success: false,
          message: error.message,
        },
        error.status || HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  /**
   * List all available backups on the server
   */
  @Public()
  @Get('list')
  @ApiOperation({ summary: 'List all available backups on the server' })
  @ApiResponse({
    status: 200,
    description: 'List of backups retrieved successfully',
    schema: {
      example: {
        success: true,
        count: 2,
        backups: [
          {
            file_name: 'backup-2025-12-27-10-30-45.tar.gz',
            size: '24.5 MB',
            created_at: '2025-12-27T10:30:45.000Z',
            last_modified: '2025-12-27T10:30:45.000Z',
            download_url: 'http://localhost:3011/backup/download/backup-2025-12-27-10-30-45.tar.gz',
            expires_in: '23h 45m'
          }
        ]
      }
    }
  })
  async listBackups() {
    try {
      const backups = await this.backupService.listBackups();
      return {
        success: true,
        count: backups.length,
        backups,
      };
    } catch (error) {
      throw new HttpException(
        {
          success: false,
          message: 'Failed to list backups',
          error: error.message,
        },
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }
}

