import "@testing-library/jest-dom/vitest";
import React from "react";
import { describe, it, expect, vi } from "vitest";
import {
  renderWithProviders as render,
  screen,
  fireEvent,
} from "../utils/test-utils";
import Avatar from "../../app/components/asset/Avatar";
import {
  componentTestSuite,
  type ComponentTestSuiteConfig,
} from "../utils/componentTestSuite";

type AvatarProps = React.ComponentProps<typeof Avatar>;

const baseProps: AvatarProps = {
  src: "/assets/marketing/avatar-1.svg",
  alt: "User avatar",
  size: "medium",
};

const config: ComponentTestSuiteConfig<AvatarProps> = {
  component: Avatar,
  name: "Avatar",
  props: baseProps,
  primaryRole: "img",
  testCases: {
    renders: true,
    accessibility: true,
    keyboardNavigation: false,
    disabledState: false,
    errorState: false,
  },
};

componentTestSuite<AvatarProps>(config);

describe("Avatar (behavioral tests)", () => {
  it("renders the image with alt text", () => {
    render(<Avatar {...baseProps} />);
    const img = screen.getByRole("img", { name: "User avatar" });
    expect(img).toHaveAttribute("src", baseProps.src);
  });

  it("does not show initials while the image is loading", () => {
    render(
      <Avatar
        src="/assets/marketing/avatar-1.svg"
        alt="Ada Lovelace"
        initials="AL"
      />,
    );
    expect(screen.queryByText("AL")).not.toBeInTheDocument();
  });

  it("applies the small photo ring after the image loads", () => {
    const { container } = render(
      <Avatar
        src="/assets/marketing/avatar-1.svg"
        alt="User avatar"
        size="small"
      />,
    );
    fireEvent.load(screen.getByRole("img", { name: "User avatar" }));
    expect(container.firstChild).toHaveClass("border-[#FFFFFF4D]");
    expect(container.firstChild).toHaveClass("box-border");
  });

  it("shows initials when src is omitted", () => {
    render(<Avatar alt="Ada Lovelace" initials="Ada Lovelace" />);
    expect(screen.getByRole("img", { name: "Ada Lovelace" })).toHaveTextContent(
      "AL",
    );
    expect(document.querySelector("img")).not.toBeInTheDocument();
  });

  it("shows a person mark when src and initials are omitted", () => {
    const { container } = render(<Avatar alt="Member" />);
    expect(screen.getByRole("img", { name: "Member" })).toBeInTheDocument();
    expect(container.querySelector("svg")).toBeInTheDocument();
    expect(document.querySelector("img")).not.toBeInTheDocument();
  });

  it("switches to initials when the image errors", () => {
    render(
      <Avatar
        src="/missing-avatar.png"
        alt="Ada Lovelace"
        initials="AL"
        size="large"
      />,
    );
    fireEvent.error(screen.getByRole("img", { name: "Ada Lovelace" }));
    expect(document.querySelector("img")).not.toBeInTheDocument();
    expect(screen.getByRole("img", { name: "Ada Lovelace" })).toHaveTextContent(
      "AL",
    );
  });

  it("applies rounded-square radius", () => {
    const { container } = render(
      <Avatar alt="Org" initials="CR" shape="rounded-square" />,
    );
    expect(container.firstChild).toHaveClass(
      "rounded-[var(--measures-radius-200,8px)]",
    );
  });

  it("applies outlined fallback chrome", () => {
    render(
      <Avatar alt="Ada Lovelace" initials="AL" variant="outlined" />,
    );
    const mark = screen.getByText("AL");
    expect(mark).toHaveClass(
      "border-[var(--color-content-default-brand-primary)]",
    );
  });

  it("renders a button with hover treatment when onClick is set", () => {
    const onClick = vi.fn();
    render(
      <Avatar alt="Ada Lovelace" initials="AL" onClick={onClick} />,
    );
    const button = screen.getByRole("button", { name: "Ada Lovelace" });
    fireEvent.click(button);
    expect(onClick).toHaveBeenCalledTimes(1);
    expect(button).toHaveClass("hover:opacity-90");
  });

  it("hides decorative fallbacks from the accessibility tree", () => {
    render(<Avatar alt="" initials="AB" />);
    expect(screen.queryByRole("img")).not.toBeInTheDocument();
  });
});
