'use server';

// src/app/upload/_actions.ts

import { auth } from "@/auth";
import { revalidatePath } from "next/cache";
import { createFileNode, getAllFolders, upsertFileNodeByHash } from "@/data-access/file-nodes";
import { prisma } from "@/lib/prisma";
import { createOneDriveFolder, uploadToFolderId, ensureOneDriveFolder } from "@/services/onedrive";
/**
 * NEW: CHECK FOR DUPLICATE HASH
 */
export async function checkDuplicateAction(hash: string) {
  const existing = await prisma.fileNode.findUnique({
    where: { hash },
    select: { name: true }
  });
  return existing;
}
/**
 * 1. CREATE VIRTUAL FOLDER
 */
export async function createFolderAction(name: string, parentId?: string | null) {
  const session = await auth();
  if (!session?.user?.id) throw new Error("Unauthorized");

  try {
    const internalId = crypto.randomUUID();
    // Swapped createNode for createFileNode
    const newNode = await createFileNode({
      id: internalId,
      oneDriveId: null,
      name,
      isFolder: true,
      path: `virtual:/${name}`,
      ownerId: session.user.id,
      parentId: parentId || null,
      metadata: { type: "FOLDER" }
    });

    revalidatePath("/dashboard");
    return { success: true, node: newNode };
  } catch (error: any) {
    throw new Error(error.message || "Failed to create virtual folder");
  }
}
/**
 * 2. UPLOAD FILE (Physical UUID Folder)
 */
export async function uploadFileAction(formData: FormData) {
  const session = await auth();
  if (!session?.user?.id) throw new Error("Unauthorized");

  const file = formData.get("file") as File;
  const hash = formData.get("hash") as string;
  const description = formData.get("description") as string || "";
  const parentIdRaw = formData.get("parentId") as string | null;
  const parentId = (parentIdRaw === "" || parentIdRaw === "root") ? null : parentIdRaw;
  
  const customMetadataRaw = formData.get("customMetadata") as string;
  const customMetadata = customMetadataRaw ? JSON.parse(customMetadataRaw) : {};

  if (!file) throw new Error("No file selected");

  const rootFolder = "WebCalibre";
  const internalId = crypto.randomUUID(); // Used for both DB ID and OneDrive Folder Name

  try {
    // A. Ensure root exists
    await ensureOneDriveFolder(session.user.id, rootFolder);

    // B. Create the physical UUID folder on OneDrive
    const subFolderRes = await createOneDriveFolder(session.user.id, rootFolder, internalId);
    const subFolderData = await subFolderRes.json();

    // C. Upload the file binary into that specific folder
    const uploadedFileData = await uploadToFolderId(session.user.id, file, subFolderData.id);

    // D. Create record in Database
   // src/app/upload/_actions.ts

// ... inside uploadFileAction or createFolderAction ...
// ... inside uploadFileAction after OneDrive work is done ...

await createFileNode({
  id: internalId, 
  oneDriveId: uploadedFileData.id,
  name: file.name,
  hash:hash,
  description: description,
  size: BigInt(file.size),
  isFolder: false,
  path: `/${rootFolder}/${internalId}/${file.name}`,
  ownerId: session.user.id,
  parentId: parentId, 
  metadata: { 
    ...customMetadata, // User's custom keys from the form
    type: file.name.split('.').pop()?.toUpperCase() || "UNKNOWN",
    mimeType: file.type 
  }
});

    revalidatePath("/dashboard");
    revalidatePath("/upload");
    return { success: true };
  } catch (error: any) {
    console.error("Upload refactor error:", error);
    return { success: false, error: error.message };
  }
}
/**
 * NEW: FETCH ALL VIRTUAL FOLDERS
 * This is the exact export the compiler is looking for.
 */
export async function getFoldersAction() {
  const session = await auth();
  if (!session?.user?.id) throw new Error("Unauthorized");

  try {
    // This calls the helper in your data-access/file-nodes.ts
    const folders = await getAllFolders();
    return folders;
  } catch (error) {
    console.error("Error in getFoldersAction:", error);
    return [];
  }
}
/**
 * EXECUTE BULK ITEM
 * Orchestrates the physical upload to OneDrive and the database record 
 * creation/update. This is the heart of the Bulk Upload and Restore system.
 */
export async function executeBulkItemAction(formData: FormData) {
  const session = await auth();
  
  // 1. Security check
  if (!session?.user?.id) {
    throw new Error("Unauthorized: You must be logged in to perform bulk actions.");
  }

  const file = formData.get("file") as File;
  const hash = formData.get("hash") as string;
  const targetFolderIdRaw = formData.get("targetFolderId") as string | null;
  
  // Standardize the target folder ID
  const targetFolderId = (targetFolderIdRaw === "" || targetFolderIdRaw === "root") 
    ? null 
    : targetFolderIdRaw;

  if (!file || !hash) {
    throw new Error("Missing required file or hash data for bulk operation.");
  }

  try {
    const rootFolder = "WebCalibre";
    // We generate a unique internal ID to serve as the physical folder name on OneDrive
    const internalId = crypto.randomUUID(); 

    // 2. Physical Storage (OneDrive)
    // Ensure the root app folder exists first
    await ensureOneDriveFolder(session.user.id, rootFolder);
    
    // Create the unique subfolder for this file (to avoid collisions and match single-upload logic)
    const subFolderRes = await createOneDriveFolder(session.user.id, rootFolder, internalId);
    const subFolderData = await subFolderRes.json();
    
    // Perform the actual binary upload
    const uploadedFileData = await uploadToFolderId(session.user.id, file, subFolderData.id);

    // 3. Database Logic (Data Access Layer)
    // We use upsertFileNodeByHash to handle the Disaster Recovery case:
    // If the hash matches an existing record, it updates the OneDrive link.
    // If not, it creates a brand new record.
    const result = await upsertFileNodeByHash({
      name: file.name,
      hash: hash,
      oneDriveId: uploadedFileData.id,
      parentId: targetFolderId,
      size: BigInt(file.size),
      ownerId: session.user.id,
    });

    // 4. Refresh UI
    revalidatePath("/dashboard");
    
    return { 
      success: true, 
      id: result.id,
      mode: result.createdAt === result.updatedAt ? 'created' : 'restored' 
    };
  } catch (error: any) {
    console.error("Bulk Item Execution Failure:", error);
    return { 
      success: false, 
      error: error.message || "An unexpected error occurred during upload." 
    };
  }
}