import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { DEFAULT_COLOR_PALETTE } from "../constants";
import { createStrictColorPalette } from "../lib";
import { OrganSvg } from "../OrganSvg";

const strictColorPalette = createStrictColorPalette(DEFAULT_COLOR_PALETTE);

describe("COLOR_PALETTES", () => {
  it("should have blue, yellow, and gray color schemes", () => {
    expect(DEFAULT_COLOR_PALETTE.blue).toBeDefined();
    expect(DEFAULT_COLOR_PALETTE.yellow).toBeDefined();
    expect(DEFAULT_COLOR_PALETTE.gray).toBeDefined();
  });

  it("each palette should have 100, 200, and 300 colors", () => {
    for (const scheme of ["blue", "yellow", "gray"] as const) {
      const palette = DEFAULT_COLOR_PALETTE[scheme];
      expect(palette[100]).toBeDefined();
      expect(palette[200]).toBeDefined();
      expect(palette[300]).toBeDefined();
    }
  });
});

describe("OrganSvg", () => {
  const defaultProps = {
    organId: "heart" as const,
    isHovered: false,
    isSelected: false,
    onMouseEnter: () => {},
    onMouseLeave: () => {},
    onClick: () => {},
    x: 0,
    y: 0,
    width: 22,
    height: 23,
    viewBox: "0 0 22 23",
  };

  it("should render with default blue color scheme when no colorScheme is provided", () => {
    render(
      <svg>
        <title>Heart</title>
        <OrganSvg colorPalette={strictColorPalette} {...defaultProps} />
      </svg>,
    );

    const organElement = screen.getByLabelText("heart");
    expect(organElement).toBeInTheDocument();

    // Check that the path has the blue base color
    const path = organElement.querySelector("path");
    expect(path).toHaveAttribute("fill", DEFAULT_COLOR_PALETTE.blue[200]);
  });

  it("should use yellow color scheme when specified", () => {
    render(
      <svg>
        <title>Heart</title>
        <OrganSvg
          colorPalette={strictColorPalette}
          {...defaultProps}
          config={{ id: "heart", colorName: "yellow" }}
        />
      </svg>,
    );

    const organElement = screen.getByLabelText("heart");
    const path = organElement.querySelector("path");
    expect(path).toHaveAttribute("fill", DEFAULT_COLOR_PALETTE.yellow[200]);
  });

  it("should use gray color scheme when specified", () => {
    render(
      <svg>
        <title>Heart</title>
        <OrganSvg
          colorPalette={strictColorPalette}
          {...defaultProps}
          config={{ id: "heart", colorName: "gray" }}
        />
      </svg>,
    );

    const organElement = screen.getByLabelText("heart");
    const path = organElement.querySelector("path");
    expect(path).toHaveAttribute("fill", DEFAULT_COLOR_PALETTE.gray[200]);
  });

  it("should use hover color when isHovered is true", () => {
    render(
      <svg>
        <title>Heart</title>
        <OrganSvg
          colorPalette={strictColorPalette}
          {...defaultProps}
          isHovered={true}
          config={{ id: "heart", colorName: "blue" }}
        />
      </svg>,
    );

    const organElement = screen.getByLabelText("heart");
    const path = organElement.querySelector("path");
    expect(path).toHaveAttribute("fill", DEFAULT_COLOR_PALETTE.blue[300]);
  });

  it("should use active color when isSelected is true", () => {
    render(
      <svg>
        <title>Heart</title>
        <OrganSvg
          colorPalette={strictColorPalette}
          {...defaultProps}
          isSelected={true}
          config={{ id: "heart", colorName: "yellow" }}
        />
      </svg>,
    );

    const organElement = screen.getByLabelText("heart");
    const path = organElement.querySelector("path");
    expect(path).toHaveAttribute("fill", DEFAULT_COLOR_PALETTE.yellow[300]);
  });

  it("should allow style override via config.style", () => {
    const customFill = "#ff0000";
    render(
      <svg>
        <title>Heart</title>
        <OrganSvg
          colorPalette={strictColorPalette}
          {...defaultProps}
          config={{ id: "heart", colorName: "blue", style: { fill: customFill } }}
        />
      </svg>,
    );

    const organElement = screen.getByLabelText("heart");
    const path = organElement.querySelector("path");
    // When not hovered/selected, user style is applied after base default
    // But since it's merged, fill should still be customFill
    expect(path).toHaveAttribute("fill", customFill);
  });
});
