import {
  act,
  assertEquals,
  cleanup,
  fireEvent,
  render,
  screen,
} from "./setup.ts";
import LoginFrame from "../../islands/LoginFrame.tsx";

// Mock fetch to prevent actual network calls
const originalFetch = globalThis.fetch;

function mockFetch(response = { success: false }) {
  globalThis.fetch = () =>
    Promise.resolve(
      new Response(JSON.stringify(response), {
        headers: { "Content-Type": "application/json" },
      }),
    );
}

function restoreFetch() {
  globalThis.fetch = originalFetch;
}

// Mock $loading to prevent errors
function mockLoading() {
  globalThis.$loading = { show: () => {}, hide: () => {} };
}

function restoreLoading() {
  delete globalThis.$loading;
}

Deno.test({
  name: "LoginFrame - login mode renders email and password inputs",
  async fn() {
    mockFetch();
    const { container } = render(<LoginFrame mode="login" />);
    // Wait for useEffect to settle
    await act(async () => {});
    assertEquals(screen.getByPlaceholderText("Your email") !== null, true);
    assertEquals(screen.getByPlaceholderText("Your password") !== null, true);
    cleanup();
    restoreFetch();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "LoginFrame - login mode renders Sign in button",
  async fn() {
    mockFetch();
    const { container } = render(<LoginFrame mode="login" />);
    await act(async () => {});
    assertEquals(screen.getByText("Sign in").tagName, "BUTTON");
    cleanup();
    restoreFetch();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "LoginFrame - login mode renders Go Register button",
  async fn() {
    mockFetch();
    render(<LoginFrame mode="login" />);
    await act(async () => {});
    assertEquals(screen.getByText("Go Register").tagName, "BUTTON");
    cleanup();
    restoreFetch();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "LoginFrame - login mode does not render confirm password",
  async fn() {
    mockFetch();
    render(<LoginFrame mode="login" />);
    await act(async () => {});
    const confirmInput = screen.queryByPlaceholderText("Confirm your password");
    assertEquals(confirmInput, null);
    cleanup();
    restoreFetch();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "LoginFrame - register mode renders confirm password input",
  fn() {
    mockFetch();
    render(<LoginFrame mode="register" />);
    assertEquals(
      screen.getByPlaceholderText("Confirm your password") !== null,
      true,
    );
    cleanup();
    restoreFetch();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "LoginFrame - register mode renders Register button",
  fn() {
    mockFetch();
    render(<LoginFrame mode="register" />);
    assertEquals(screen.getByText("Register").tagName, "BUTTON");
    cleanup();
    restoreFetch();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "LoginFrame - register mode renders Go Login button",
  fn() {
    mockFetch();
    render(<LoginFrame mode="register" />);
    assertEquals(screen.getByText("Go Login").tagName, "BUTTON");
    cleanup();
    restoreFetch();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "LoginFrame - submit with empty fields sets error state",
  async fn() {
    mockFetch();
    mockLoading();
    render(<LoginFrame mode="login" />);
    await act(async () => {});

    const submitBtn = screen.getByText("Sign in");
    await act(async () => {
      fireEvent.click(submitBtn);
    });

    // Check that error borders appear on empty inputs
    const emailInput = screen.getByPlaceholderText("Your email");
    const passwordInput = screen.getByPlaceholderText("Your password");
    assertEquals(emailInput.className.includes("border-red-600"), true);
    assertEquals(passwordInput.className.includes("border-red-600"), true);

    cleanup();
    restoreFetch();
    restoreLoading();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

Deno.test({
  name: "LoginFrame - typing clears error state",
  async fn() {
    mockFetch();
    mockLoading();
    render(<LoginFrame mode="login" />);
    await act(async () => {});

    // Trigger error
    await act(async () => {
      fireEvent.click(screen.getByText("Sign in"));
    });

    const emailInput = screen.getByPlaceholderText("Your email");
    assertEquals(emailInput.className.includes("border-red-600"), true);

    // Type into the email input to clear error
    await act(async () => {
      fireEvent.input(emailInput, { target: { value: "test@email.com" } });
    });
    assertEquals(emailInput.className.includes("border-red-600"), false);

    cleanup();
    restoreFetch();
    restoreLoading();
  },
  sanitizeResources: false,
  sanitizeOps: false,
});
