import { apiRequest } from './api';

export interface S3UploadResult {
  success: boolean;
  fileKey?: string;
  fileUrl?: string;
  error?: string;
}

/**
 * Uploads a file directly to AWS S3 bucket via presigned PutObject URL.
 * Bypasses backend server payload limits and stores video directly in S3.
 */
export async function uploadDirectToS3(
  file: File,
  category: string = 'lessons-videos',
  onProgress?: (progressPercent: number) => void
): Promise<S3UploadResult> {
  try {
    // Step 1: Request S3 presigned upload URL from Next.js backend API
    const presignedRes = await apiRequest('/upload/presigned-url', {
      method: 'POST',
      body: JSON.stringify({
        filename: file.name,
        fileType: file.type || 'video/mp4',
        category,
      }),
    });

    if (!presignedRes.success || !presignedRes.uploadUrl) {
      return {
        success: false,
        error: presignedRes.error || 'Failed to obtain S3 presigned upload URL from server',
      };
    }

    // Step 2: Attempt direct browser-to-S3 upload via Presigned URL
    let directSuccess = false;

    try {
      await new Promise<void>((resolve, reject) => {
        const xhr = new XMLHttpRequest();

        if (onProgress) {
          xhr.upload.onprogress = (event) => {
            if (event.lengthComputable) {
              const percent = Math.round((event.loaded / event.total) * 95);
              onProgress(percent);
            }
          };
        }

        xhr.open('PUT', presignedRes.uploadUrl, true);
        xhr.setRequestHeader('Content-Type', file.type || 'video/mp4');

        xhr.onload = () => {
          if (xhr.status === 200 || xhr.status === 204) {
            directSuccess = true;
            resolve();
          } else {
            reject(new Error(`S3 direct upload failed with status ${xhr.status}`));
          }
        };

        xhr.onerror = () => reject(new Error('Network error during direct AWS S3 video upload.'));
        xhr.send(file);
      });
    } catch (directErr) {
      console.warn('Direct S3 upload failed or connection reset. Falling back to server S3 proxy upload...', directErr);
    }

    if (directSuccess) {
      if (onProgress) onProgress(100);
      return {
        success: true,
        fileKey: presignedRes.fileKey,
        fileUrl: presignedRes.fileUrl,
      };
    }

    // Step 3: Fallback - Upload file via backend server /api/upload (which streams directly into S3)
    const formData = new FormData();
    formData.append('file', file);
    formData.append('category', category);

    const uploadRes = await apiRequest('/upload', {
      method: 'POST',
      body: formData,
    });

    if (uploadRes.success && (uploadRes.fileKey || uploadRes.filename)) {
      if (onProgress) onProgress(100);
      return {
        success: true,
        fileKey: uploadRes.fileKey || uploadRes.filename,
        fileUrl: uploadRes.fileUrl || uploadRes.url,
      };
    }

    return {
      success: false,
      error: uploadRes.error || 'Failed to upload video to AWS S3 bucket',
    };
  } catch (err: any) {
    return {
      success: false,
      error: err.message || 'Error uploading file directly to AWS S3',
    };
  }
}
