import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { AddVendorButton } from "@/app/(portal)/admin/vendors/vendor-form";

vi.mock("next/navigation", () => ({
  useRouter: () => ({ push: vi.fn(), refresh: vi.fn() }),
}));

// The form imports server actions; stub them so the client component renders in jsdom.
vi.mock("@/app/(portal)/admin/vendors/actions", () => ({
  createVendor: vi.fn(),
  updateVendor: vi.fn(),
  toggleVendorActive: vi.fn(),
}));

const GSTIN = "27AAHCP5787B1Z6"; // 15 chars

describe("VendorForm — GSTIN CAPTCHA popup (issue #114)", () => {
  beforeEach(() => {
    global.fetch = vi.fn(async () =>
      new Response(JSON.stringify({ captchaBase64: "ABC123", sessionId: "sess-1" }), {
        headers: { "Content-Type": "application/json" },
      }),
    ) as unknown as typeof fetch;
  });

  afterEach(() => {
    vi.restoreAllMocks();
  });

  async function openFormAndLookup() {
    render(<AddVendorButton simple />);
    fireEvent.click(screen.getByText("+ Add Vendor"));
    const gstinInput = screen.getByPlaceholderText(/27AAHCP5787B1Z6/);
    fireEvent.change(gstinInput, { target: { value: GSTIN } });
    fireEvent.click(screen.getByText("Look up"));
    // Popup renders the CAPTCHA prompt once the fetch resolves.
    await screen.findByText(/Enter the code shown in the image/i);
  }

  it("opens the CAPTCHA in a popup with a Cancel/Close control, leaving the form footer reachable", async () => {
    await openFormAndLookup();
    // The CAPTCHA lives in its own popup …
    expect(screen.getByRole("heading", { name: /GSTIN CAPTCHA/i })).toBeTruthy();
    // Both the form's ✕ and the popup's ✕/Cancel close controls are present.
    expect(screen.getAllByLabelText("Close").length).toBeGreaterThanOrEqual(2);
    expect(screen.getAllByText("Cancel").length).toBeGreaterThanOrEqual(2);
    // … and the underlying vendor form's submit button is still rendered (never displaced).
    expect(screen.getByText("Create Vendor")).toBeTruthy();
  });

  it("closes the popup on Cancel without closing the vendor form", async () => {
    await openFormAndLookup();
    // The popup's Cancel is the first one in the DOM (the CAPTCHA section precedes the footer).
    fireEvent.click(screen.getAllByText("Cancel")[0]);
    await waitFor(() => {
      expect(screen.queryByText(/Enter the code shown in the image/i)).toBeNull();
    });
    // The vendor form itself stays open.
    expect(screen.getByText("Create Vendor")).toBeTruthy();
    expect(screen.queryByRole("heading", { name: /GSTIN CAPTCHA/i })).toBeNull();
  });

  it("verifies the CAPTCHA, fills the form fields, and closes the popup on success", async () => {
    (global.fetch as ReturnType<typeof vi.fn>).mockImplementation(async (url: string) => {
      if (String(url).includes("/api/gst/captcha")) {
        return new Response(JSON.stringify({ captchaBase64: "ABC123", sessionId: "sess-1" }), {
          headers: { "Content-Type": "application/json" },
        });
      }
      return new Response(
        JSON.stringify({
          legalName: "Acme Pvt Ltd",
          tradeName: "Acme",
          address: "1 Dock Rd",
          pincode: "400001",
          gstin: GSTIN,
          status: "Active",
          registrationDate: "2020-01-01",
        }),
        { headers: { "Content-Type": "application/json" } },
      );
    });

    await openFormAndLookup();
    fireEvent.change(screen.getByPlaceholderText("6 digits"), { target: { value: "123456" } });
    fireEvent.click(screen.getByText("Verify"));

    // Popup closes; success line + populated fields appear on the form.
    await waitFor(() => {
      expect(screen.queryByText(/Enter the code shown in the image/i)).toBeNull();
    });
    expect((screen.getByDisplayValue("Acme") as HTMLInputElement)).toBeTruthy();
    expect(screen.getByText(/Acme Pvt Ltd — Active/)).toBeTruthy();
  });
});
