import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { render } from "solid-js/web";
import type { JSX } from "solid-js";

import PasswordInput from "./PasswordInput";
import SocialAuthButtons from "./SocialAuthButtons";
import AuthLayout from "./AuthLayout";
import { Input, Button } from "~/components/ui";

function mount(comp: () => JSX.Element): HTMLDivElement {
  const container = document.createElement("div");
  document.body.appendChild(container);
  render(() => comp(), container);
  return container;
}

beforeEach(() => {
  document.body.innerHTML = "";
  if (!globalThis.crypto) {
    Object.defineProperty(globalThis, "crypto", { value: {} });
  }
  (globalThis.crypto as unknown as Record<string, unknown>).randomUUID = vi.fn(
    () => "test-uuid-1234",
  );
});

afterEach(() => {
  document.body.innerHTML = "";
});

describe("PasswordInput", () => {
  it("renders with label", () => {
    mount(() => <PasswordInput label="Password" />);
    expect(document.body.textContent).toContain("Password");
    expect(document.querySelector("label")).toBeTruthy();
  });

  it("renders password type by default", () => {
    mount(() => <PasswordInput label="Password" />);
    const input = document.querySelector("input")!;
    expect(input.getAttribute("type")).toBe("password");
  });

  it("toggles visibility when eye icon is clicked", () => {
    mount(() => <PasswordInput label="Password" />);
    const input = document.querySelector("input")!;
    const toggle = document.querySelector("button[aria-label]")!;

    expect(input.getAttribute("type")).toBe("password");
    expect(toggle.getAttribute("aria-label")).toBe("Show password");

    toggle.dispatchEvent(new MouseEvent("click", { bubbles: true }));
    expect(input.getAttribute("type")).toBe("text");
    expect(toggle.getAttribute("aria-label")).toBe("Hide password");

    toggle.dispatchEvent(new MouseEvent("click", { bubbles: true }));
    expect(input.getAttribute("type")).toBe("password");
  });

  it("shows error message", () => {
    mount(() => (
      <PasswordInput label="Password" error="Password is required" />
    ));
    expect(document.body.textContent).toContain("Password is required");
  });

  it("shows helper text when no error", () => {
    mount(() => (
      <PasswordInput label="Password" helperText="At least 8 characters" />
    ));
    expect(document.body.textContent).toContain("At least 8 characters");
  });

  it("hides helper text when error is present", () => {
    mount(() => (
      <PasswordInput
        label="Password"
        error="Required"
        helperText="Helper text"
      />
    ));
    expect(document.body.textContent).toContain("Required");
    expect(document.body.textContent).not.toContain("Helper text");
  });

  it("forwards onInput handler", () => {
    const onInput = vi.fn();
    mount(() => <PasswordInput onInput={onInput} />);
    const input = document.querySelector("input")!;
    input.dispatchEvent(new InputEvent("input", { bubbles: true }));
    expect(onInput).toHaveBeenCalled();
  });
});

describe("SocialAuthButtons", () => {
  it("renders Google and Apple buttons", () => {
    mount(() => <SocialAuthButtons />);
    const buttons = document.querySelectorAll("button");
    expect(buttons.length).toBe(2);
    expect(buttons[0].textContent).toContain("Google");
    expect(buttons[1].textContent).toContain("Apple");
  });

  it("renders SVG icons in each button", () => {
    mount(() => <SocialAuthButtons />);
    const buttons = document.querySelectorAll("button");
    expect(buttons[0].querySelector("svg")).toBeTruthy();
    expect(buttons[1].querySelector("svg")).toBeTruthy();
  });
});

describe("AuthLayout", () => {
  it("renders children inside the form card", () => {
    mount(() => (
      <AuthLayout>
        <p>Form content</p>
      </AuthLayout>
    ));
    expect(document.body.textContent).toContain("Form content");
  });

  it("renders Kordant branding", () => {
    mount(() => (
      <AuthLayout>
        <p>Content</p>
      </AuthLayout>
    ));
    expect(document.body.textContent).toContain("Kordant");
  });

  it("renders gradient-card wrapper", () => {
    mount(() => (
      <AuthLayout>
        <p>Content</p>
      </AuthLayout>
    ));
    expect(document.querySelector(".gradient-card")).toBeTruthy();
  });

  it("renders testimonial text", () => {
    mount(() => (
      <AuthLayout>
        <p>Content</p>
      </AuthLayout>
    ));
    expect(document.body.textContent).toContain("Kordant");
    expect(document.body.textContent).toContain("AI-Powered Identity Protection");
  });
});
