import { afterEach, describe, expect, it, vi } from "vitest";
import { extractActaLookupDictionary, mapLookupDictionaryToActaFields } from "@/lib/extraction/extractFields";
import { extractActaDataWithAiBaseline } from "@/lib/extraction/aiExtractFields";

const SAMPLE_TEXT = `
  Escritura publica numero 7789.
  En la ciudad de Monterrey, Nuevo Leon.
  La denominacion social sera: Comercializadora Delta S.A. de C.V.
  Objeto social: Comercializacion e importacion de equipo industrial.
  Notario Publico numero 10 del estado de Nuevo Leon, Lic. Carlos Mendoza.
`;

describe("extractActaDataWithAiBaseline", () => {
  const originalApiKey = process.env.OPENAI_API_KEY;
  const originalModel = process.env.OPENAI_ACTA_MODEL;

  afterEach(() => {
    process.env.OPENAI_API_KEY = originalApiKey;
    process.env.OPENAI_ACTA_MODEL = originalModel;
    vi.unstubAllGlobals();
  });

  it("uses AI as primary engine when OpenAI returns valid JSON", async () => {
    process.env.OPENAI_API_KEY = "test-key";
    process.env.OPENAI_ACTA_MODEL = "gpt-test-model";

    const lookupDictionary = extractActaLookupDictionary(SAMPLE_TEXT);
    const fields = mapLookupDictionaryToActaFields(lookupDictionary);

    vi.stubGlobal(
      "fetch",
      vi.fn(async () =>
        new Response(
          JSON.stringify({
            model: "gpt-test-model",
            usage: {
              prompt_tokens: 111,
              completion_tokens: 222,
              total_tokens: 333,
            },
            choices: [
              {
                message: {
                  content: JSON.stringify({
                    fields,
                    lookupDictionary,
                  }),
                },
              },
            ],
          }),
          { status: 200, headers: { "Content-Type": "application/json" } },
        ),
      ),
    );

    const result = await extractActaDataWithAiBaseline(SAMPLE_TEXT);

    expect(result.engine).toBe("ai");
    expect(result.warnings).toEqual([]);
    expect(result.fields.name).toBe(fields.name);
    expect(result.lookupDictionary.instrumentNumber).toBe(lookupDictionary.instrumentNumber);
    expect(result.usage?.totalTokens).toBe(333);
  });

  it("normalizes structured AI field values (e.g. object addresses) without fallback", async () => {
    process.env.OPENAI_API_KEY = "test-key";

    vi.stubGlobal(
      "fetch",
      vi.fn(async () =>
        new Response(
          JSON.stringify({
            model: "gpt-test-model",
            choices: [
              {
                message: {
                  content: JSON.stringify({
                    fields: {
                      name: "TREISOLE",
                      rfc: "SHOULD_BE_IGNORED",
                      legalRepresentative: "MARCELO DARES BALLI",
                      incorporationDate: "2025-04-04",
                      deedNumber: null,
                      notaryName: null,
                      fiscalAddress: {
                        calle: "Lazaro Garza Ayala",
                        numeroExterior: "205",
                        entidadFederativa: "NUEVO LEON",
                      },
                      businessPurpose: "Comercio al por menor",
                      stateOfIncorporation: "NUEVO LEON",
                    },
                    lookupDictionary: {
                      version: "mx_acta_constitutiva_reference_v1",
                    },
                  }),
                },
              },
            ],
          }),
          { status: 200, headers: { "Content-Type": "application/json" } },
        ),
      ),
    );

    const result = await extractActaDataWithAiBaseline(SAMPLE_TEXT);

    expect(result.engine).toBe("ai");
    expect(result.fields.rfc).toBeNull();
    expect(result.fields.fiscalAddress).toContain("Lazaro Garza Ayala");
    expect(result.fields.fiscalAddress).toContain("205");
  });

  it("falls back to regex extraction when AI request fails", async () => {
    process.env.OPENAI_API_KEY = "test-key";

    vi.stubGlobal(
      "fetch",
      vi.fn(async () => {
        throw new Error("network error");
      }),
    );

    const result = await extractActaDataWithAiBaseline(SAMPLE_TEXT);

    expect(result.engine).toBe("regex_fallback");
    expect(result.warnings[0]).toContain("AI extraction fallo");
    expect(result.fields.name).toBe("Comercializadora Delta S.A. de C.V");
    expect(result.lookupDictionary.notaryNumber).toBe("10");
  });
});
