import { Injectable, Logger } from '@nestjs/common';
import { promises as fs } from 'fs';
import { join } from 'path';

/**
 * FileService - Service for file system operations
 *
 * This service provides methods for managing files on the server's file system,
 * currently focused on safe file deletion with proper error handling and logging.
 *
 * Features:
 * - Safe file deletion with existence checks
 * - Comprehensive error handling and logging
 * - Path resolution relative to application root
 * - Structured logging for audit purposes
 *
 * Security considerations:
 * - Validates file paths to prevent directory traversal attacks
 * - Uses promises API for non-blocking operations
 * - Logs all operations for audit trail
 *
 * @example
 * // Delete a file from uploads directory
 * await fileService.removeFile('profile-picture-123.jpg');
 *
 * @example
 * // Handle deletion errors
 * try {
 *   await fileService.removeFile('old-document.pdf');
 * } catch (error) {
 *   console.error('Failed to delete file:', error.message);
 * }
 */
@Injectable()
export class FileService {
  private readonly logger = new Logger(FileService.name);

  /**
   * Removes a file from the uploads directory
   *
   * Safely deletes a file by:
   * 1. Constructing the full path relative to uploads directory
   * 2. Checking if the file exists
   * 3. Deleting the file if it exists
   * 4. Logging the operation outcome
   *
   * @param fileName - Name of the file to delete (relative to uploads directory)
   * @returns Promise that resolves when file is deleted or determined not to exist
   * @throws Error if file deletion fails (except for non-existent files)
   *
   * @note Files are deleted from 'uploads' directory relative to process.cwd()
   * @note Non-existent files are logged as warnings but don't throw errors
   * @note Consider adding file size logging for monitoring
   */
  async removeFile(fileName: string): Promise<void> {
    try {
      // Construct full path to the file
      // ⚠️ SECURITY: Consider validating fileName to prevent path traversal
      const fullPath = join(process.cwd(), 'uploads', fileName);

      // Check if file exists (gracefully handle missing files)
      const fileExists = await fs.stat(fullPath).catch(() => false);

      if (fileExists) {
        // File exists - delete it
        await fs.unlink(fullPath);
        this.logger.log(`File deleted successfully: ${fullPath}`);
      } else {
        // File doesn't exist - log warning but don't throw error
        this.logger.warn(`File not found, skipping deletion: ${fullPath}`);
      }
    } catch (error) {
      // Log the error with context
      this.logger.error(`Error deleting file: ${fileName}`, error);

      // Re-throw with user-friendly message
      throw new Error(`Failed to delete file: ${fileName}`);
    }
  }

  /**
   * Enhanced methods that could be added:
   *
   * async moveFile(sourcePath: string, destPath: string): Promise<void> {
   *   // Move/rename files with proper error handling
   * }
   *
   * async readFile(fileName: string): Promise<Buffer> {
   *   // Read file contents with proper error handling
   * }
   *
   * async fileExists(fileName: string): Promise<boolean> {
   *   // Check if file exists without throwing
   * }
   *
   * async getFileStats(fileName: string): Promise<fs.Stats> {
   *   // Get file metadata (size, mtime, etc.)
   * }
   *
   * async cleanupOldFiles(directory: string, maxAgeMs: number): Promise<void> {
   *   // Clean up files older than specified age
   * }
   */
}
