/**
 * Live integration gate (Agent G) — requires core-api + seeded DB.
 *
 * Run: CORE_API_LIVE_TEST=true npm run test:contract:live
 * Prereq: mpgis-farmer-platform up with `npm run db:seed` (or dev:stack)
 */
import { describe, it, expect, beforeAll } from "vitest";
import {
  DASHBOARD_MOCKUP_PERSONAS,
  DASHBOARD_PERSONA_IDS,
} from "@/lib/fixtures/dashboard-mockup-personas";
import {
  assertFarmerDashboardV2Persona,
  assertFinanceModuleV2,
  assertIdentityModuleV2,
  assertInputsModuleV2,
} from "./schema-assert";

const LIVE = process.env.CORE_API_LIVE_TEST === "true";
const CORE_API_URL = process.env.CORE_API_URL ?? "http://localhost:4000";
const BFF_URL = process.env.AGNET_BFF_URL ?? "http://localhost:3000";
const DEV_OTP = "1234";

async function loginCoreApi(phone: string): Promise<{ token: string; userId: string }> {
  const otpRes = await fetch(`${CORE_API_URL}/auth/otp`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ phone, countryCode: "UZ" }),
  });
  expect(otpRes.ok, `OTP request failed: ${otpRes.status}`).toBe(true);

  const verifyRes = await fetch(`${CORE_API_URL}/auth/verify`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ phone, code: DEV_OTP, countryCode: "UZ" }),
  });
  expect(verifyRes.ok, `OTP verify failed: ${verifyRes.status}`).toBe(true);

  const body = (await verifyRes.json()) as { accessToken: string; user: { id: string } };
  return { token: body.accessToken, userId: body.user.id };
}

async function fetchDashboard(token: string, viaBff = false): Promise<Response> {
  const url = viaBff ? `${BFF_URL}/api/farmer/dashboard` : `${CORE_API_URL}/farmer/dashboard`;
  return fetch(url, {
    headers: {
      Authorization: `Bearer ${token}`,
      Accept: "application/json",
    },
  });
}

describe.skipIf(!LIVE)("Dashboard v2 live core-api (Agent G)", () => {
  let coreApiReachable = false;

  beforeAll(async () => {
    try {
      const res = await fetch(`${CORE_API_URL}/auth/otp`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ phone: "+998900000000", countryCode: "UZ" }),
        signal: AbortSignal.timeout(3000),
      });
      coreApiReachable = res.ok || res.status === 400;
    } catch {
      coreApiReachable = false;
    }
  });

  it("core-api is reachable", () => {
    expect(coreApiReachable, `core-api not reachable at ${CORE_API_URL}`).toBe(true);
  });

  it("islomjon persona returns IdentityModuleV2 from live API", async () => {
    const persona = DASHBOARD_MOCKUP_PERSONAS.islomjon;
    const { token, userId } = await loginCoreApi(persona.phone);
    expect(userId).toBe(DASHBOARD_PERSONA_IDS.islomjon);

    const res = await fetchDashboard(token);
    expect(res.status).toBe(200);
    const data = await res.json();
    assertFarmerDashboardV2Persona(data, "identity");
    assertIdentityModuleV2(data.identity);
    expect(data.identity?.farmerId).toBe("AGID-FMR-00142");
    expect(data.identity?.gis?.areaHa).toBe(4.52);
  });

  it("agrobank persona returns FinanceModuleV2 aligned with fixture", async () => {
    const persona = DASHBOARD_MOCKUP_PERSONAS.agrobankCase;
    const { token, userId } = await loginCoreApi(persona.phone);
    expect(userId).toBe(DASHBOARD_PERSONA_IDS.agrobankCase);

    const res = await fetchDashboard(token);
    expect(res.status).toBe(200);
    const data = await res.json();
    assertFarmerDashboardV2Persona(data, "finance");
    assertFinanceModuleV2(data.finance);

    expect(data.finance?.caseId).toBe("UZB-2024-05-000789");
    expect(data.finance?.eligibilityScore).toBe(78);
    expect(data.finance?.eligibilityLabel).toBe("High");
    expect(data.finance?.routedInstitution?.name).toBe("Agrobank (UZ)");
    expect(data.finance?.bankMatches).toHaveLength(4);
    expect(data.finance?.documents).toHaveLength(7);
    expect(data.finance?.stages?.[0]?.label).toBe("Case Created");
    expect(data.finance?.stages?.[0]?.timestamp).toBeTruthy();
    expect(data.identity?.fullName).toBe("Islomjon Abdullaev");
    expect(data.identity?.region).toBe("Tashkent");
    expect(data.trade?.crops?.[0]?.crop).toBe("Wheat");
  });

  it("burkina persona returns InputsModuleV2 from live API", async () => {
    const persona = DASHBOARD_MOCKUP_PERSONAS.burkinaInputs;
    const { token, userId } = await loginCoreApi(persona.phone);
    expect(userId).toBe(DASHBOARD_PERSONA_IDS.burkinaInputs);

    const res = await fetchDashboard(token);
    expect(res.status).toBe(200);
    const data = await res.json();
    assertFarmerDashboardV2Persona(data, "inputs");
    assertInputsModuleV2(data.inputs);
    expect(data.inputs?.kpis?.seed).toBe(12);
    expect(data.inputs?.voucher?.code).toBe("VCH-2026-8842");
  });
});

describe.skipIf(!LIVE || !process.env.AGNET_BFF_LIVE_TEST)("Dashboard v2 live BFF proxy (Agent G)", () => {
  it("BFF /api/farmer/dashboard proxies agrobank finance persona", async () => {
    const { token } = await loginCoreApi(DASHBOARD_MOCKUP_PERSONAS.agrobankCase.phone);

    const res = await fetchDashboard(token, true);
    expect(res.status).toBe(200);
    const data = await res.json();
    expect(data.finance?.caseId).toBe("UZB-2024-05-000789");
  });
});
