import { NextResponse } from "next/server";
import { EpayClient } from "@/modules/parcel-sync/services/epay-client";
import {
  createEpaySession,
  getEpayCredentials,
} from "@/modules/parcel-sync/services/epay-session-store";
import { enqueueBatch } from "@/modules/parcel-sync/services/epay-queue";
import { storeCfExtract } from "@/modules/parcel-sync/services/epay-storage";
import { prisma } from "@/core/storage/prisma";

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

/* ------------------------------------------------------------------ */
/*  Dedup for test order step (prevents re-enqueue on page refresh)    */
/* ------------------------------------------------------------------ */

type TestOrderEntry = {
  timestamp: number;
  extractIds: string[];
  parcels: Array<{ nrCadastral: string; uatName: string; siruta: string; extractId: string | undefined }>;
};

const TEST_ORDER_DEDUP_TTL_MS = 30_000; // 30 seconds

const gTestDedup = globalThis as {
  __testOrderDedup?: TestOrderEntry | null;
};
if (gTestDedup.__testOrderDedup === undefined) gTestDedup.__testOrderDedup = null;

/**
 * GET /api/ancpi/test?step=login|uats|order|download
 *
 * ePay internal county IDs = eTerra WORKSPACE_IDs.
 * ePay UAT IDs = SIRUTA codes.
 * Zero discovery calls needed!
 */
export async function GET(req: Request) {
  const url = new URL(req.url);
  const step = url.searchParams.get("step") ?? "login";

  const username = process.env.ANCPI_USERNAME ?? "";
  const password = process.env.ANCPI_PASSWORD ?? "";

  if (!username || !password) {
    return NextResponse.json({ error: "ANCPI credentials not configured" });
  }

  try {
    // ── login ──
    if (step === "login") {
      const client = await EpayClient.create(username, password);
      const credits = await client.getCredits();
      createEpaySession(username, password, credits);
      return NextResponse.json({ step: "login", success: true, credits });
    }

    // ── uats ── Verify that ePay county/UAT IDs match our WORKSPACE_ID/SIRUTA
    if (step === "uats") {
      const client = await EpayClient.create(username, password);
      await client.addToCart(14200);

      // Get county list to confirm IDs match WORKSPACE_IDs
      const counties = await client.getCountyList();
      const clujCounty = counties.find((c) =>
        c.value.toUpperCase().includes("CLUJ"),
      );

      // Get UAT list to confirm IDs match SIRUTA codes
      let uatList: { id: number; value: string }[] = [];
      if (clujCounty) {
        uatList = await client.getUatList(clujCounty.id);
      }

      return NextResponse.json({
        step: "uats",
        totalCounties: counties.length,
        clujCounty,
        note: clujCounty?.id === 127
          ? "CONFIRMED: ePay county ID = WORKSPACE_ID (127)"
          : `WARNING: expected 127, got ${clujCounty?.id}`,
        totalUats: uatList.length,
        clujNapoca: uatList.find((u) => u.id === 54975),
        feleacu: uatList.find((u) => u.id === 57582),
        floresti: uatList.find((u) => u.id === 57706),
      });
    }

    // ── download ── Re-download PDFs from all known ePay orders
    if (step === "download") {
      const client = await EpayClient.create(username, password);
      createEpaySession(username, password, await client.getCredits());

      // All known order IDs (MinIO + DB were cleaned, need re-download)
      // Single orders: mapping unknown — use documentsByCadastral to discover CF
      const singleOrderIds = ["9685480", "9685481", "9685482", "9685483", "9685484"];
      // Batch orders: documentsByCadastral maps CF -> doc correctly
      const batchOrderIds = ["9685487", "9685488"];
      const allOrderIds = [...singleOrderIds, ...batchOrderIds];

      // UAT name lookup for DB records
      const uatLookup: Record<string, { uatId: number; uatName: string }> = {
        "345295": { uatId: 54975, uatName: "Cluj-Napoca" },
        "63565": { uatId: 57582, uatName: "Feleacu" },
        "88089": { uatId: 57706, uatName: "Floresti" },
        "61904": { uatId: 57582, uatName: "Feleacu" },
        "309952": { uatId: 54975, uatName: "Cluj-Napoca" },
      };

      const results: Array<{
        orderId: string;
        nrCadastral: string;
        status: string;
        documents: number;
        downloaded: boolean;
        minioPath?: string;
        error?: string;
      }> = [];

      for (const orderId of allOrderIds) {
        try {
          // Get order status — documentsByCadastral maps CF → doc
          const orderStatus = await client.getOrderStatus(orderId);
          console.log(
            `[ancpi-test] Order ${orderId}: status=${orderStatus.status}, docs=${orderStatus.documents.length}, byCF=${orderStatus.documentsByCadastral.size}`,
          );

          if (orderStatus.documents.length === 0) {
            results.push({
              orderId,
              nrCadastral: "unknown",
              status: orderStatus.status,
              documents: 0,
              downloaded: false,
              error: "No documents found in order",
            });
            continue;
          }

          // Process each document by cadastral number from the map
          if (orderStatus.documentsByCadastral.size > 0) {
            for (const [cfNumber, doc] of orderStatus.documentsByCadastral) {
              if (!doc.downloadValabil || doc.contentType !== "application/pdf") {
                results.push({
                  orderId,
                  nrCadastral: cfNumber,
                  status: orderStatus.status,
                  documents: orderStatus.documents.length,
                  downloaded: false,
                  error: "Document not downloadable or not PDF",
                });
                continue;
              }

              try {
                // Download the PDF
                const pdfBuffer = await client.downloadDocument(doc.idDocument, 4);
                console.log(
                  `[ancpi-test] Downloaded doc ${doc.idDocument} (CF ${cfNumber}): ${pdfBuffer.length} bytes`,
                );

                // Resolve UAT info for this cadastral number
                const uat = uatLookup[cfNumber];
                const uatId = uat?.uatId ?? 0;
                const uatName = uat?.uatName ?? "Necunoscut";

                // Store in MinIO
                const { path, index } = await storeCfExtract(
                  pdfBuffer,
                  cfNumber,
                  {
                    "ancpi-order-id": orderId,
                    "nr-cadastral": cfNumber,
                    judet: "CLUJ",
                    uat: uatName,
                    "data-document": doc.dataDocument ?? "",
                    stare: orderStatus.status,
                    produs: "EXI_ONLINE",
                  },
                );

                // Calculate dates
                const documentDate = doc.dataDocument
                  ? new Date(doc.dataDocument)
                  : new Date();
                const expiresAt = new Date(documentDate);
                expiresAt.setDate(expiresAt.getDate() + 30);

                // Always create new records (DB was cleaned)
                // Increment version for duplicate parcels
                const maxVersion = await prisma.cfExtract.aggregate({
                  where: { nrCadastral: cfNumber },
                  _max: { version: true },
                });

                await prisma.cfExtract.create({
                  data: {
                    orderId,
                    nrCadastral: cfNumber,
                    nrCF: cfNumber,
                    judetIndex: 127,
                    judetName: "CLUJ",
                    uatId,
                    uatName,
                    status: "completed",
                    epayStatus: orderStatus.status,
                    idDocument: doc.idDocument,
                    documentName: doc.nume,
                    documentDate,
                    minioPath: path,
                    minioIndex: index,
                    completedAt: new Date(),
                    expiresAt,
                    version: (maxVersion._max.version ?? 0) + 1,
                  },
                });

                results.push({
                  orderId,
                  nrCadastral: cfNumber,
                  status: orderStatus.status,
                  documents: orderStatus.documents.length,
                  downloaded: true,
                  minioPath: path,
                });
              } catch (dlErr) {
                const msg = dlErr instanceof Error ? dlErr.message : String(dlErr);
                console.error(
                  `[ancpi-test] Failed to download doc for CF ${cfNumber} in order ${orderId}:`,
                  msg,
                );
                results.push({
                  orderId,
                  nrCadastral: cfNumber,
                  status: "error",
                  documents: orderStatus.documents.length,
                  downloaded: false,
                  error: msg,
                });
              }
            }
          } else {
            // Fallback: no CF mapping, process first downloadable document
            const doc = orderStatus.documents.find(
              (d) => d.downloadValabil && d.contentType === "application/pdf",
            );
            if (!doc) {
              results.push({
                orderId,
                nrCadastral: "unknown",
                status: orderStatus.status,
                documents: orderStatus.documents.length,
                downloaded: false,
                error: "No downloadable PDF and no CF mapping found",
              });
              continue;
            }

            // Try to extract CF from document name (e.g. "Extras_Informare_345295.pdf")
            const cfFromName = doc.nume.match(/(\d{4,})/)?.[1] ?? "unknown";

            const pdfBuffer = await client.downloadDocument(doc.idDocument, 4);
            console.log(
              `[ancpi-test] Downloaded doc ${doc.idDocument} (CF from name: ${cfFromName}): ${pdfBuffer.length} bytes`,
            );

            const uat = uatLookup[cfFromName];
            const uatId = uat?.uatId ?? 0;
            const uatName = uat?.uatName ?? "Necunoscut";

            const { path, index } = await storeCfExtract(
              pdfBuffer,
              cfFromName,
              {
                "ancpi-order-id": orderId,
                "nr-cadastral": cfFromName,
                judet: "CLUJ",
                uat: uatName,
                "data-document": doc.dataDocument ?? "",
                stare: orderStatus.status,
                produs: "EXI_ONLINE",
              },
            );

            const documentDate = doc.dataDocument
              ? new Date(doc.dataDocument)
              : new Date();
            const expiresAt = new Date(documentDate);
            expiresAt.setDate(expiresAt.getDate() + 30);

            const maxVersion = await prisma.cfExtract.aggregate({
              where: { nrCadastral: cfFromName },
              _max: { version: true },
            });

            await prisma.cfExtract.create({
              data: {
                orderId,
                nrCadastral: cfFromName,
                nrCF: cfFromName,
                judetIndex: 127,
                judetName: "CLUJ",
                uatId,
                uatName,
                status: "completed",
                epayStatus: orderStatus.status,
                idDocument: doc.idDocument,
                documentName: doc.nume,
                documentDate,
                minioPath: path,
                minioIndex: index,
                completedAt: new Date(),
                expiresAt,
                version: (maxVersion._max.version ?? 0) + 1,
              },
            });

            results.push({
              orderId,
              nrCadastral: cfFromName,
              status: orderStatus.status,
              documents: orderStatus.documents.length,
              downloaded: true,
              minioPath: path,
            });
          }
        } catch (error) {
          const message =
            error instanceof Error ? error.message : String(error);
          console.error(
            `[ancpi-test] Failed to process order ${orderId}:`,
            message,
          );
          results.push({
            orderId,
            nrCadastral: "unknown",
            status: "error",
            documents: 0,
            downloaded: false,
            error: message,
          });
        }
      }

      return NextResponse.json({
        step: "download",
        totalOrders: allOrderIds.length,
        results,
        summary: {
          downloaded: results.filter((r) => r.downloaded).length,
          failed: results.filter((r) => !r.downloaded).length,
        },
      });
    }

    // ── order ── Batch order test (USES 2 CREDITS!)
    // Uses enqueueBatch to create ONE ePay order for all parcels
    if (step === "order") {
      // ── Dedup check: prevent re-enqueue on page refresh ──
      const prevEntry = gTestDedup.__testOrderDedup;
      if (
        prevEntry &&
        Date.now() - prevEntry.timestamp < TEST_ORDER_DEDUP_TTL_MS
      ) {
        console.log(
          `[ancpi-test] Order dedup hit: returning cached response (${Math.round((Date.now() - prevEntry.timestamp) / 1000)}s ago)`,
        );
        return NextResponse.json({
          step: "order",
          deduplicated: true,
          message: `Dedup: batch was enqueued ${Math.round((Date.now() - prevEntry.timestamp) / 1000)}s ago — returning cached IDs.`,
          extractIds: prevEntry.extractIds,
          parcels: prevEntry.parcels,
        });
      }

      if (!getEpayCredentials()) {
        createEpaySession(username, password, 0);
      }

      const client = await EpayClient.create(username, password);
      const credits = await client.getCredits();
      createEpaySession(username, password, credits);

      const parcels = [
        {
          nrCadastral: "61904",
          siruta: "57582",
          judetIndex: 127,
          judetName: "CLUJ",
          uatId: 57582,
          uatName: "Feleacu",
        },
        {
          nrCadastral: "309952",
          siruta: "54975",
          judetIndex: 127,
          judetName: "CLUJ",
          uatId: 54975,
          uatName: "Cluj-Napoca",
        },
      ];

      if (credits < parcels.length) {
        return NextResponse.json({
          error: `Doar ${credits} credite, trebuie ${parcels.length}.`,
        });
      }

      // Use enqueueBatch — ONE order for all parcels
      const ids = await enqueueBatch(parcels);

      const parcelResults = parcels.map((p, i) => ({
        nrCadastral: p.nrCadastral,
        uatName: p.uatName,
        siruta: p.siruta,
        extractId: ids[i],
      }));

      // ── Store in dedup cache ──
      gTestDedup.__testOrderDedup = {
        timestamp: Date.now(),
        extractIds: ids,
        parcels: parcelResults,
      };

      return NextResponse.json({
        step: "order",
        credits,
        message: `Enqueued batch of ${ids.length} parcels as ONE order.`,
        extractIds: ids,
        parcels: parcelResults,
      });
    }

    return NextResponse.json({ error: `Unknown step: ${step}` });
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    console.error(`[ancpi-test] Step ${step} failed:`, message);
    return NextResponse.json({ error: message, step }, { status: 500 });
  }
}
