import { NextRequest, NextResponse } from "next/server";
import { EterraClient } from "@/modules/parcel-sync/services/eterra-client";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

/**
 * Strip Romanian diacritics and replace non-alphanumeric chars with underscores.
 */
function sanitizeFilename(raw: string): string {
  return raw
    .replace(/[ăâ]/g, "a")
    .replace(/[ĂÂ]/g, "A")
    .replace(/[îÎ]/g, "i")
    .replace(/[țȚ]/g, "t")
    .replace(/[șȘ]/g, "s")
    .replace(/[^a-zA-Z0-9._-]/g, "_")
    .replace(/_+/g, "_")
    .replace(/^_|_$/g, "");
}

/**
 * Extract file extension from content-type or server filename.
 */
function getExtension(contentType: string, serverFilename: string): string {
  // Try extension from server filename first
  const dotIdx = serverFilename.lastIndexOf(".");
  if (dotIdx > 0) {
    return serverFilename.slice(dotIdx + 1).toLowerCase();
  }
  // Fallback to content-type mapping
  const map: Record<string, string> = {
    "application/pdf": "pdf",
    "image/png": "png",
    "image/jpeg": "jpg",
    "application/zip": "zip",
    "application/xml": "xml",
    "text/xml": "xml",
  };
  return map[contentType] ?? "pdf";
}

/**
 * GET /api/eterra/rgi/download-doc?workspaceId=127&applicationId=X&documentPk=Y&documentTypeId=Z&docType=...&appNo=...&initialAppNo=...
 *
 * Downloads an issued document from eTerra RGI.
 * Tries server-side download first. If that fails (some documents are
 * restricted to the current actor), returns a JSON blocked response
 * so the frontend can show a soft message.
 */
export async function GET(req: NextRequest) {
  try {
    const workspaceId = req.nextUrl.searchParams.get("workspaceId");
    const applicationId = req.nextUrl.searchParams.get("applicationId");
    const documentPk = req.nextUrl.searchParams.get("documentPk");
    const documentTypeId = req.nextUrl.searchParams.get("documentTypeId");
    const docType = req.nextUrl.searchParams.get("docType");
    const appNo = req.nextUrl.searchParams.get("appNo");
    const initialAppNo = req.nextUrl.searchParams.get("initialAppNo");

    if (!workspaceId || !applicationId || !documentPk) {
      return NextResponse.json(
        { error: "workspaceId, applicationId and documentPk required" },
        { status: 400 },
      );
    }

    const username = process.env.ETERRA_USERNAME ?? "";
    const password = process.env.ETERRA_PASSWORD ?? "";
    if (!username || !password) {
      return NextResponse.json({ error: "Credentials missing" }, { status: 500 });
    }

    const client = await EterraClient.create(username, password);

    // Step 0: Set application context (like the web UI does)
    // This call sets session-level attributes required for document access
    try {
      await client.rgiGet(
        `appDetail/verifyCurrentActorAuthenticated/${applicationId}/${workspaceId}`,
      );
    } catch {
      // Non-critical
    }

    // Also load application details (sets more session context)
    try {
      await client.rgiPost(
        `rgi/appdetail/details?applicationid=${applicationId}`,
      );
    } catch {
      // Non-critical
    }

    // Try fileVisibility
    let available = false;
    if (documentTypeId) {
      try {
        const vis = await client.rgiGet(
          `rgi/appdetail/issueddocs/fileVisibility/${workspaceId}/${applicationId}/${documentTypeId}`,
        );
        if (vis && typeof vis === "object" && (vis as Record<string, unknown>).msg === "OK") {
          available = true;
        }
      } catch {
        // Not available — will try direct download anyway
      }
    }

    // Try download (even if fileVisibility failed — context might be enough)
    try {
      const { data, contentType, filename: serverFilename } = await client.rgiDownload(
        `rgi/appdetail/loadDocument/downloadFile/${workspaceId}/${documentPk}`,
      );
      if (data.length > 0) {
        // Build meaningful filename from query params, fallback to server filename
        const ext = getExtension(contentType, serverFilename);
        let filename: string;
        if (docType && appNo) {
          filename = `${sanitizeFilename(docType)}_${sanitizeFilename(appNo)}.${ext}`;
        } else if (docType) {
          filename = `${sanitizeFilename(docType)}.${ext}`;
        } else if (appNo) {
          filename = `document_${sanitizeFilename(appNo)}.${ext}`;
        } else {
          // Use server filename, but still sanitize it
          const serverBase = serverFilename.replace(/\.[^.]+$/, "");
          filename = serverBase && serverBase !== "document"
            ? `${sanitizeFilename(serverBase)}.${ext}`
            : serverFilename;
        }

        return new NextResponse(new Uint8Array(data), {
          status: 200,
          headers: {
            "Content-Type": contentType,
            "Content-Disposition": `attachment; filename="${encodeURIComponent(filename)}"`,
            "Content-Length": String(data.length),
          },
        });
      }
    } catch {
      // Fall through to blocked response
    }

    // Server-side download not available — return soft blocked response
    // so the frontend can show a user-friendly message
    return NextResponse.json(
      {
        blocked: true,
        message: "Documentul nu este inca disponibil pentru descarcare din eTerra.",
      },
      { status: 200 },
    );
  } catch (error) {
    const message = error instanceof Error ? error.message : "Eroare server";
    return NextResponse.json({ error: message }, { status: 500 });
  }
}
