import React, { isValidElement } from "react";
import { describe, expect, it } from "vitest";
import ForgotPasswordPageClient from "./forgot-password/ForgotPasswordPageClient";
import ResetPasswordPageClient from "./reset-password/ResetPasswordPageClient";
import ForgotPasswordPage from "./forgot-password/page";
import ResetPasswordPage from "./reset-password/page";
import AcceptInvitePage from "./onboarding/accept-invite/page";
import SignUpForm from "./sign-up/[[...sign-up]]/SignUpForm";
import SignUpPage from "./sign-up/[[...sign-up]]/page";

function collectText(node: unknown): string[] {
  if (node === null || node === undefined || typeof node === "boolean")
    return [];
  if (typeof node === "string" || typeof node === "number")
    return [String(node)];
  if (Array.isArray(node)) return node.flatMap(collectText);
  if (isValidElement<{ children?: React.ReactNode }>(node))
    return collectText(node.props.children);
  return [];
}

type ElementWithHref = { children?: React.ReactNode; href?: string; embedded?: boolean }

function findElement(
  node: unknown,
  predicate: (element: React.ReactElement<ElementWithHref>) => boolean,
): React.ReactElement<ElementWithHref> | null {
  if (node === null || node === undefined || typeof node === "boolean")
    return null;
  if (Array.isArray(node)) {
    for (const child of node) {
      const found = findElement(child, predicate);
      if (found) return found;
    }
    return null;
  }
  if (!isValidElement<ElementWithHref>(node)) return null;
  if (predicate(node)) return node;
  return findElement(node.props.children, predicate);
}

describe("dashboard public auth pages", () => {
  it("renders forgot-password with public chrome by default", async () => {
    const page = await ForgotPasswordPage({
      searchParams: Promise.resolve({}),
    });

    expect(isValidElement(page)).toBe(true);
    expect(page.type).toBe(ForgotPasswordPageClient);
    expect(page.props.embedded).toBe(false);
  });

  it("renders forgot-password in embedded mode when requested", async () => {
    const page = await ForgotPasswordPage({
      searchParams: Promise.resolve({ embedded: "1" }),
    });

    expect(isValidElement(page)).toBe(true);
    expect(page.type).toBe(ForgotPasswordPageClient);
    expect(page.props.embedded).toBe(true);
  });

  it("renders sign-up in embedded mode when requested", async () => {
    const page = await SignUpPage({
      searchParams: Promise.resolve({ embedded: "1" }),
    });

    expect(isValidElement(page)).toBe(true);
    expect(page.type).toBe(React.Suspense);
    const child = page.props.children;
    expect(isValidElement(child)).toBe(true);
    expect(child.type).toBe(SignUpForm);
    expect(child.props.embedded).toBe(true);
  });

  it("renders reset-password in embedded mode for the public shell route", () => {
    const page = ResetPasswordPage();

    expect(isValidElement(page)).toBe(true);
    expect(page.type).toBe(ResetPasswordPageClient);
    expect(page.props.embedded).toBe(true);
  });

  it("keeps accept-invite copy and sign-in handoff visible", () => {
    const page = AcceptInvitePage();
    const text = collectText(page).join(" ");
    const signInLink = findElement(
      page,
      (element) => element.props.href === "/sign-in",
    );

    expect(text).toContain("Invitation accepted");
    expect(text).toContain("Sign in to dashboard");
    expect(signInLink).not.toBeNull();
  });
});
