import {
  ref as storageRef,
  uploadBytes,
  getDownloadURL,
  deleteObject,
} from 'firebase/storage';
import type { BoardItem, UploadFilesOptions, FileItem } from '@/types';
import { UploadSettings } from '@/data/config';

// 3. Upload single file and return download URL , with upload progress ui
export const uploadFileAndGetURL = async (
  file: File,
  path: string
): Promise<string> => {
  const { $firebase } = useNuxtApp();
  const storage = $firebase.storage;
  const fileRef = storageRef(storage, path);
  console.log(`[uploadFileAndGetURL] Uploading file to: ${path}`);
  await uploadBytes(fileRef, file);
  const downloadURL = await getDownloadURL(fileRef);
  console.log(
    `[uploadFileAndGetURL] Uploaded and retrieved URL: ${downloadURL}`
  );
  return downloadURL;
};

// 4. Delete a file from storage
export const deleteUploadedFile = async (url: string) => {
  const { $firebase } = useNuxtApp();
  const storage = $firebase.storage;
  if (!url) return;
  const fileRef = storageRef(storage, url);
  console.log(`[deleteUploadedFile] Deleting file at: ${url}`);
  await deleteObject(fileRef);
  console.log(`[deleteUploadedFile] Deleted: ${url}`);
};

// 5. Upload thumbnail
export const handleThumbnailUpload = async ({
  newThumbnail,
  oldThumbnailUrl,
  deleteThumbnail,
  boardId,
  currentBoard,
}: {
  newThumbnail: File | null;
  oldThumbnailUrl?: string;
  deleteThumbnail?: boolean;
  boardId: string;
  currentBoard: string;
}): Promise<{ name: string; url: string } | null> => {
  if (newThumbnail && UploadSettings.isImageFile(newThumbnail)) {
    const thumbPath = `thumbnails/${currentBoard}/${boardId}/${newThumbnail.name}`;
    console.log(
      `[handleThumbnailUpload] Uploading thumbnail: ${newThumbnail.name}`
    );
    const thumbUrl = await uploadFileAndGetURL(newThumbnail, thumbPath);
    console.log(`[handleThumbnailUpload] Thumbnail uploaded: ${thumbUrl}`);
    return { name: newThumbnail.name, url: thumbUrl };
  }

  if (deleteThumbnail && oldThumbnailUrl) {
    console.log(
      `[handleThumbnailUpload] Deleting existing thumbnail: ${oldThumbnailUrl}`
    );
    await deleteUploadedFile(oldThumbnailUrl);
    console.log(`[handleThumbnailUpload] Thumbnail deleted`);
    return { name: '', url: '' };
  }

  console.log(`[handleThumbnailUpload] No change to thumbnail`);
  return null;
};
// 6. Upload or delete board files
export const handleFileUpdates = async ({
  newFiles,
  oldFiles = [],
  deleteFileIndexes = [],
  currentBoard,
  boardId,
}: {
  newFiles: File[];
  oldFiles?: FileItem[];
  deleteFileIndexes?: number[];
  currentBoard: string;
  boardId: string;
}): Promise<FileItem[]> => {
  const result: FileItem[] = [];

  console.log(
    `[handleFileUpdates] Retaining files: ${
      oldFiles.length - deleteFileIndexes.length
    }, Deleting: ${deleteFileIndexes.length}`
  );

  for (const [idx, file] of oldFiles.entries()) {
    if (!deleteFileIndexes.includes(idx)) {
      result.push(file);
    } else {
      console.log(`[handleFileUpdates] Deleting file: ${file.name}`);
      await deleteUploadedFile(file.url);
    }
  }

  const totalFileCount = result.length + newFiles.length;
  if (totalFileCount > UploadSettings.MAX_TOTAL_FILES) {
    console.error(
      `[handleFileUpdates] Upload exceeds max file count: ${totalFileCount}/${UploadSettings.MAX_TOTAL_FILES}`
    );
    throw new Error(
      `최대 ${UploadSettings.MAX_TOTAL_FILES}개의 파일만 업로드할 수 있습니다.`
    );
  }

  for (const file of newFiles) {
    const filePath = `boards/${currentBoard}/${boardId}/files/${file.name}`;
    console.log(
      `[handleFileUpdates] Uploading file: ${file.name} (${file.size} bytes)`
    );
    const url = await uploadFileAndGetURL(file, filePath);
    console.log(`[handleFileUpdates] File uploaded: ${url}`);
    result.push({ name: file.name, url });
  }

  console.log(`[handleFileUpdates] Total files now: ${result.length}`);
  return result;
};

// 7. Orchestrate full board file + thumbnail upload
export const uploadFiles = async ({
  newBoardData,
  newThumbnail,
  newFiles,
  oldThumbnailUrl,
  oldFiles = [],
  deleteThumbnail = false,
  deleteFileIndexes = [],
  currentBoard,
}: UploadFilesOptions): Promise<BoardItem> => {
  const boardId = newBoardData.docId;
  console.log(
    `[uploadFiles] Starting upload for boardId: ${boardId}, board: ${currentBoard}`
  );

  const thumbnail = await handleThumbnailUpload({
    newThumbnail,
    oldThumbnailUrl,
    deleteThumbnail,
    boardId,
    currentBoard,
  });
  if (thumbnail) {
    console.log(`[uploadFiles] Thumbnail set: ${thumbnail.url}`);
    newBoardData.thumbnail = thumbnail;
  }

  newBoardData.files = await handleFileUpdates({
    newFiles,
    oldFiles,
    deleteFileIndexes,
    currentBoard,
    boardId,
  });

  console.log(`[uploadFiles] Upload complete for board: ${boardId}`);
  return newBoardData;
};
