// src/app/dashboard/actions.ts

'use server';

import { auth } from "@/auth";
import { revalidatePath } from "next/cache";
import { 
  getAllFileNodes, 
  getFileNodeById, 
  updateFileNode, 
  deleteFileNode 
} from "@/data-access/file-nodes";
import { 
  getOneDriveItem, 
  deleteFromOneDrive, 
  uploadToOneDrive 
} from "@/services/onedrive";

//import { getEnrichedMetadataFromCloud } from "@/data-access/file-nodes";

import { getFreshAccessToken } from "@/lib/auth-utils";

import { getOneDriveFileBuffer } from "@/services/onedrive"; // Import your working service
import { extractMetadata } from "@/lib/metadata-extractor";


/**
 * 1. FETCH: Get all file nodes
 * Now simply calls the DAL. Error handling is left to the caller (the UI).
 */
export async function getFileNodes() {
  return await getAllFileNodes();
}

/**
 * 2. DOWNLOAD: Generates the authenticated OneDrive URL
 * Orchestrates the session check, DAL lookup, and Service call.
 */
export async function getDownloadUrlAction(id: string) {
  const session = await auth();
  if (!session?.user?.id) throw new Error("Unauthorized");

  const file = await getFileNodeById(id);
  if (!file || !file.oneDriveId) throw new Error("File not found or missing cloud ID");

  // Service handles token refresh and graph request internally
  const data = await getOneDriveItem(session.user.id, file.oneDriveId);
  const downloadUrl = data["@microsoft.graph.downloadUrl"];

  if (!downloadUrl) throw new Error("OneDrive did not provide a download URL");
  return downloadUrl;
}

/**
 * 3. DELETE: Removes from both Cloud and Database
 */
export async function deleteFileNodeAction(id: string) {
  const session = await auth();
  if (!session?.user?.id) throw new Error("Unauthorized");

  try {
    const file = await getFileNodeById(id);
    if (!file) throw new Error("File record not found");

    // Phase 1: Cloud Deletion
    if (file.oneDriveId) {
      await deleteFromOneDrive(session.user.id, file.oneDriveId);
    }

    // Phase 2: Database Deletion
    await deleteFileNode(id);

    revalidatePath("/dashboard");
    return { success: true };
  } catch (error) {
    console.error("Delete Error:", error);
    return { success: false, error: "Failed to delete file" };
  }
}

/**
 * 4. UPDATE: Modify record and optionally sync new content to OneDrive
 */
export async function updateFileNodeAction(id: string, formData: FormData) {
  const session = await auth();
  if (!session?.user?.id) throw new Error("Unauthorized");

  const name = formData.get("name") as string;
  const description = formData.get("description") as string;
  const parentIdRaw = formData.get("parentId") as string;
  const metadataStr = formData.get("metadata") as string;
  const newFile = formData.get("file") as File | null;

  const parentId = parentIdRaw === "root" ? null : parentIdRaw;
  let metadata = JSON.parse(metadataStr);

  try {
    const node = await getFileNodeById(id);

    // If a new file is uploaded, push it to OneDrive first
    if (newFile && newFile.size > 0 && node?.oneDriveId) {
      await uploadToOneDrive(session.user.id, newFile, node.oneDriveId);

      metadata.type = newFile.name.split('.').pop()?.toUpperCase() || 'UNKNOWN';
      metadata.mimeType = newFile.type;
    }

    // Update the database via DAL
    await updateFileNode(id, {
      name,
      description,
      parentId,
      metadata,
      size: newFile ? BigInt(newFile.size) : undefined,
    });

    revalidatePath("/dashboard");
    return { success: true };
  } catch (error) {
    console.error("Update Error:", error);
    return { success: false, error: "Failed to update record" };
  }
}




export async function getMetadataPreviewAction(fileId: string) {
  const session = await auth();
  if (!session?.user?.id) throw new Error("Unauthorized");

  try {
    const node = await getFileNodeById(fileId);
    if (!node || !node.oneDriveId) throw new Error("No OneDrive ID found");

    console.log(`📡 Attempting fetch via Service for: ${node.name}`);

    const token = await getFreshAccessToken(session.user.id); 
    
    if (!token) throw new Error("Could not retrieve access token");
    // Call your existing service
    const buffer = await getOneDriveFileBuffer(node.oneDriveId, token);
    
    console.log(`📦 Buffer received: ${buffer.length} bytes`);

    const extractedData = await extractMetadata(buffer, node.name);
    
    console.log("✅ Extracted:", extractedData);
    return { success: true, data: extractedData };

  } catch (error: any) {
    console.error("❌ Service Fetch Error:", error.message);
    // If this still says ENOTFOUND, the code is fine, but the terminal is blocked.
    return { success: false, error: error.message };
  }
}