// ABOUTME: Unit tests for DayCell component.
// ABOUTME: Tests phase coloring, today highlighting, and click handling.
import { fireEvent, render, screen } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import type { CyclePhase } from "@/types";
import { DayCell } from "./day-cell";

describe("DayCell", () => {
  const baseProps = {
    date: new Date("2026-01-15"),
    cycleDay: 5,
    phase: "FOLLICULAR" as CyclePhase,
    isToday: false,
    onClick: vi.fn(),
  };

  describe("rendering", () => {
    it("renders the day number from date", () => {
      render(<DayCell {...baseProps} date={new Date("2026-01-15")} />);

      expect(screen.getByText("15")).toBeInTheDocument();
    });

    it("renders the cycle day label", () => {
      render(<DayCell {...baseProps} cycleDay={5} />);

      expect(screen.getByText("Day 5")).toBeInTheDocument();
    });

    it("renders as a button", () => {
      render(<DayCell {...baseProps} />);

      expect(screen.getByRole("button")).toBeInTheDocument();
    });

    it("renders cycle day 1 correctly", () => {
      render(<DayCell {...baseProps} cycleDay={1} />);

      expect(screen.getByText("Day 1")).toBeInTheDocument();
    });

    it("renders high cycle day numbers", () => {
      render(<DayCell {...baseProps} cycleDay={28} />);

      expect(screen.getByText("Day 28")).toBeInTheDocument();
    });
  });

  describe("phase colors", () => {
    it("applies blue background for MENSTRUAL phase", () => {
      render(<DayCell {...baseProps} phase="MENSTRUAL" />);

      const button = screen.getByRole("button");
      expect(button).toHaveClass("bg-blue-100");
    });

    it("applies green background for FOLLICULAR phase", () => {
      render(<DayCell {...baseProps} phase="FOLLICULAR" />);

      const button = screen.getByRole("button");
      expect(button).toHaveClass("bg-green-100");
    });

    it("applies purple background for OVULATION phase", () => {
      render(<DayCell {...baseProps} phase="OVULATION" />);

      const button = screen.getByRole("button");
      expect(button).toHaveClass("bg-purple-100");
    });

    it("applies yellow background for EARLY_LUTEAL phase", () => {
      render(<DayCell {...baseProps} phase="EARLY_LUTEAL" />);

      const button = screen.getByRole("button");
      expect(button).toHaveClass("bg-yellow-100");
    });

    it("applies red background for LATE_LUTEAL phase", () => {
      render(<DayCell {...baseProps} phase="LATE_LUTEAL" />);

      const button = screen.getByRole("button");
      expect(button).toHaveClass("bg-red-100");
    });
  });

  describe("today highlighting", () => {
    it("does not have ring when isToday is false", () => {
      render(<DayCell {...baseProps} isToday={false} />);

      const button = screen.getByRole("button");
      expect(button).not.toHaveClass("ring-2", "ring-black");
    });

    it("has ring-2 ring-black when isToday is true", () => {
      render(<DayCell {...baseProps} isToday={true} />);

      const button = screen.getByRole("button");
      expect(button).toHaveClass("ring-2", "ring-black");
    });

    it("maintains phase color when isToday is true", () => {
      render(<DayCell {...baseProps} phase="OVULATION" isToday={true} />);

      const button = screen.getByRole("button");
      expect(button).toHaveClass("bg-purple-100");
      expect(button).toHaveClass("ring-2", "ring-black");
    });
  });

  describe("click handling", () => {
    it("calls onClick when clicked", () => {
      const onClick = vi.fn();
      render(<DayCell {...baseProps} onClick={onClick} />);

      const button = screen.getByRole("button");
      fireEvent.click(button);

      expect(onClick).toHaveBeenCalledTimes(1);
    });

    it("does not throw when onClick is undefined", () => {
      render(<DayCell {...baseProps} onClick={undefined} />);

      const button = screen.getByRole("button");
      expect(() => fireEvent.click(button)).not.toThrow();
    });

    it("calls onClick once per click", () => {
      const onClick = vi.fn();
      render(<DayCell {...baseProps} onClick={onClick} />);

      const button = screen.getByRole("button");
      fireEvent.click(button);
      fireEvent.click(button);
      fireEvent.click(button);

      expect(onClick).toHaveBeenCalledTimes(3);
    });
  });

  describe("styling", () => {
    it("has rounded corners", () => {
      render(<DayCell {...baseProps} />);

      const button = screen.getByRole("button");
      expect(button).toHaveClass("rounded");
    });

    it("has padding", () => {
      render(<DayCell {...baseProps} />);

      const button = screen.getByRole("button");
      expect(button).toHaveClass("p-2");
    });

    it("renders day number with font-medium", () => {
      render(<DayCell {...baseProps} date={new Date("2026-01-15")} />);

      const dayNumber = screen.getByText("15");
      expect(dayNumber).toHaveClass("font-medium");
    });

    it("renders cycle day label in gray", () => {
      render(<DayCell {...baseProps} cycleDay={5} />);

      const cycleLabel = screen.getByText("Day 5");
      expect(cycleLabel).toHaveClass("text-gray-500");
    });
  });

  describe("date variations", () => {
    it("renders single digit day", () => {
      render(<DayCell {...baseProps} date={new Date("2026-01-05")} />);

      expect(screen.getByText("5")).toBeInTheDocument();
    });

    it("renders last day of month", () => {
      render(<DayCell {...baseProps} date={new Date("2026-01-31")} />);

      expect(screen.getByText("31")).toBeInTheDocument();
    });

    it("renders first day of month", () => {
      render(<DayCell {...baseProps} date={new Date("2026-02-01")} />);

      expect(screen.getByText("1")).toBeInTheDocument();
    });
  });
});
