import { Controller, Get, Param, Req, Res, UseGuards, Logger, Request, Post, UseInterceptors, UploadedFile, Body } from '@nestjs/common';
import { Response } from 'express';
import { DocumentsService } from './documents.service';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { S3Service } from '../s3/s3.service';
import { FileInterceptor } from '@nestjs/platform-express';

interface S3File {
  buffer: Buffer;
  contentType: string;
  contentLength: number;
  fileName: string;
}

@Controller('documents')
export class DocumentsController {
  private readonly logger = new Logger(DocumentsController.name);

  constructor(
    private readonly documentsService: DocumentsService,
    private readonly s3Service: S3Service
  ) {
    this.logger.log('DocumentsController initialized');
  }

  @Post('upload')
  @UseGuards(JwtAuthGuard)
  @UseInterceptors(FileInterceptor('file'))
  async uploadDocument(
    @UploadedFile() file: Express.Multer.File,
    @Body('title') title: string,
    @Body('sharedWithId') sharedWithId: string,
    @Request() req,
  ) {
    this.logger.log('=== Document upload endpoint hit ===');
    this.logger.debug('Upload request received:', {
      fileName: file?.originalname,
      fileSize: file?.size,
      title,
      sharedWithId,
      uploadedById: req.user.id,
    });

    try {
      const result = await this.documentsService.uploadDocument(
        file,
        title,
        Number(sharedWithId),
        req.user.id,
      );
      
      this.logger.debug('Document upload successful:', {
        documentId: result.id,
        title: result.title,
        s3Key: result.s3Key,
      });
      
      return result;
    } catch (error) {
      this.logger.error('Document upload failed:', {
        error: error.message,
        stack: error.stack,
      });
      throw error;
    }
  }

  @Get('shared/:userId')
  @UseGuards(JwtAuthGuard)
  async getSharedDocuments(@Param('userId') userId: string) {
    return this.documentsService.getClientDocuments(Number(userId));
  }

  @Get('download/:key')
  @UseGuards(JwtAuthGuard)
  async downloadDocument(
    @Param('key') key: string,
    @Request() req,
    @Res() res: Response
  ) {
    try {
      this.logger.debug(`Download request for key: ${key}`);
      
      const decodedKey = decodeURIComponent(key);
      this.logger.debug(`Decoded key: ${decodedKey}`);

      // Get document from database first to verify access
      const document = await this.documentsService.findDocumentByS3Key(decodedKey);
      
      if (!document) {
        return res.status(404).json({ message: 'Document not found' });
      }

      // Verify user has access to this document
      const hasAccess = await this.documentsService.verifyDocumentAccess(
        document.id,
        req.user.id
      );

      if (!hasAccess) {
        return res.status(403).json({ message: 'Access denied' });
      }

      // Get the file from S3
      const file = await this.s3Service.getFile(decodedKey);
      
      if (!file || !file.buffer) {
        return res.status(404).json({ message: 'File not found in storage' });
      }

      res.set({
        'Content-Type': file.contentType || 'application/octet-stream',
        'Content-Length': file.contentLength,
        'Content-Disposition': `attachment; filename="${encodeURIComponent(file.fileName)}"`,
      });

      return res.send(file.buffer);
    } catch (error) {
      this.logger.error('Download error:', error);
      return res.status(500).json({ 
        message: 'Failed to download file',
        error: error.message 
      });
    }
  }
}
