// @vitest-environment jsdom

import { act } from "react";
import { createRoot } from "react-dom/client";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import type { AssistantHomeStatus } from "../../hooks/useAssistantHomeStatus";
import {
  AssistantHomeGreeting,
  buildGreetingMarkdown,
} from "./AssistantHomeGreeting";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any).IS_REACT_ACT_ENVIRONMENT = true;

function emptyStatus(partial: Partial<AssistantHomeStatus> = {}): AssistantHomeStatus {
  return {
    activeAgents: 0,
    pendingGates: [],
    recentCompletions: [],
    staleProjects: [],
    companyPrefix: "NEX",
    loading: false,
    ...partial,
  };
}

describe("buildGreetingMarkdown", () => {
  const morning = new Date("2026-04-11T09:00:00");
  const afternoon = new Date("2026-04-11T14:00:00");
  const evening = new Date("2026-04-11T20:00:00");

  it("picks the correct greeting based on hour and includes the user name", () => {
    const status = emptyStatus();
    expect(buildGreetingMarkdown(status, "Mikkel", morning)).toContain("Good morning, Mikkel.");
    expect(buildGreetingMarkdown(status, "Mikkel", afternoon)).toContain("Good afternoon, Mikkel.");
    expect(buildGreetingMarkdown(status, "Mikkel", evening)).toContain("Good evening, Mikkel.");
  });

  it("drops the name suffix when no user name is provided", () => {
    const body = buildGreetingMarkdown(emptyStatus(), null, morning);
    expect(body).toContain("Good morning.");
    expect(body).not.toContain("Good morning,");
  });

  it("shows a quiet-state message when everything is empty", () => {
    const body = buildGreetingMarkdown(emptyStatus(), "Mikkel", morning);
    expect(body).toContain("Everything's quiet right now");
    expect(body).toContain("What do you want to do?");
  });

  it("lists active agents, pending gates, completions and stale projects as bullets", () => {
    const status = emptyStatus({
      activeAgents: 2,
      pendingGates: [
        {
          id: "g1",
          projectName: "nexus",
          gateName: "Phase 4 audit",
          href: "/NEX/approvals/g1",
        },
      ],
      recentCompletions: [
        {
          id: "c1",
          projectName: "nexus",
          summary: "Phase 4 shipped",
          when: "2h ago",
        },
      ],
      staleProjects: [
        {
          id: "p1",
          name: "personal-finance",
          lastActivity: "3d ago",
          href: "/NEX/projects/personal-finance",
        },
      ],
    });
    const body = buildGreetingMarkdown(status, "Mikkel", morning);
    expect(body).toContain("2 agents currently working");
    expect(body).toContain("nexus: Phase 4 audit awaiting approval");
    expect(body).toContain("nexus: Phase 4 shipped (2h ago)");
    expect(body).toContain("personal-finance: idle 3d ago");
    expect(body).toContain("Since we last talked:");
  });

  it("uses singular form when there is exactly one active agent", () => {
    const body = buildGreetingMarkdown(
      emptyStatus({ activeAgents: 1 }),
      null,
      morning,
    );
    expect(body).toContain("1 agent currently working");
    expect(body).not.toContain("1 agents");
  });
});

describe("<AssistantHomeGreeting />", () => {
  let container: HTMLDivElement;
  let root: ReturnType<typeof createRoot> | null = null;

  beforeEach(() => {
    container = document.createElement("div");
    document.body.appendChild(container);
    root = null;
  });

  afterEach(() => {
    if (root) {
      act(() => {
        root!.unmount();
      });
      root = null;
    }
    if (container.parentNode) container.remove();
  });

  function render(node: React.ReactNode) {
    root = createRoot(container);
    act(() => {
      root!.render(node);
    });
  }

  it("renders a loading placeholder while status.loading is true", () => {
    render(
      <AssistantHomeGreeting
        status={emptyStatus({ loading: true })}
        userName="Mikkel"
        now={new Date("2026-04-11T09:00:00")}
      />,
    );
    expect(container.querySelector('[data-testid="assistant-home-greeting-loading"]')).not.toBeNull();
    expect(container.querySelector('[data-testid="assistant-home-greeting"]')).toBeNull();
  });

  it("renders a greeting article with the user name when not loading", () => {
    render(
      <AssistantHomeGreeting
        status={emptyStatus({ activeAgents: 3 })}
        userName="Mikkel"
        now={new Date("2026-04-11T09:00:00")}
      />,
    );
    const article = container.querySelector('[data-testid="assistant-home-greeting"]');
    expect(article).not.toBeNull();
    expect(article?.textContent ?? "").toContain("Good morning, Mikkel.");
    expect(article?.textContent ?? "").toContain("3 agents currently working");
  });

  it("renders stale project entries when provided", () => {
    render(
      <AssistantHomeGreeting
        status={emptyStatus({
          staleProjects: [
            {
              id: "p1",
              name: "personal-finance",
              lastActivity: "5d ago",
              href: "/NEX/projects/personal-finance",
            },
          ],
        })}
        userName="Mikkel"
        now={new Date("2026-04-11T09:00:00")}
      />,
    );
    const article = container.querySelector('[data-testid="assistant-home-greeting"]');
    expect(article?.textContent ?? "").toContain("personal-finance: idle 5d ago");
  });
});
