import { render } from "@testing-library/react";
import { vi } from "vitest";

import { Countdown } from "../Countdown";
import CountdownStatic from "../Countdown.static";

describe("Countdown static behavior", () => {
  it("warns when data-countdown-config JSON is invalid", () => {
    const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});

    const element = document.createElement("div");
    element.className = "countdown";
    element.setAttribute("data-countdown-config", "{invalid");

    new CountdownStatic(element);

    expect(warnSpy).toHaveBeenCalled();

    warnSpy.mockRestore();
  });

  it("updates visible units from current time", () => {
    vi.useFakeTimers();
    vi.setSystemTime(new Date("2026-07-24T00:00:00.000Z"));

    const { container } = render(
      <Countdown
        targetDate="2026-07-25T01:02:03.000Z"
        units={["days", "hours", "seconds"]}
      />,
    );

    const countdownElement = container.querySelector("[data-countdown]");
    const countdown = CountdownStatic.getInstance(countdownElement);

    countdown?.start();

    const values = Array.from(
      container.querySelectorAll(".countdown__top .countdown__value"),
    ).map((element) => element.textContent);

    expect(values).toEqual(["01", "01", "123"]);

    countdown?.destroy();
    vi.useRealTimers();
  });

  it("sets all value layers on initial render", () => {
    vi.useFakeTimers();
    vi.setSystemTime(new Date("2026-07-24T00:00:00.000Z"));

    const { container } = render(
      <Countdown targetDate="2026-07-25T01:02:03.000Z" />,
    );

    const values = Array.from(
      container
        .querySelectorAll(".countdown__unit")[0]
        .querySelectorAll(".countdown__value"),
    ).map((element) => element.textContent);

    expect(values).toEqual(["01", "01", "01", "01"]);

    vi.useRealTimers();
  });

  it("switches day label based on remaining value", () => {
    vi.useFakeTimers();
    vi.setSystemTime(new Date("2026-07-24T00:00:00.000Z"));

    const { container } = render(
      <Countdown targetDate="2026-07-25T00:00:00.000Z" units={["days"]} />,
    );

    const announcement = container.querySelector(".countdown__announcement");

    expect(announcement).toHaveTextContent("1 deň");

    vi.useRealTimers();
  });

  it("adds flipping state class when value changes", () => {
    vi.useFakeTimers();
    vi.setSystemTime(new Date("2026-07-24T00:00:00.000Z"));

    const { container } = render(
      <Countdown targetDate="2026-07-24T00:00:02.000Z" units={["seconds"]} />,
    );

    const unit = container.querySelector(".countdown__unit");

    vi.advanceTimersByTime(1000);

    expect(unit).toHaveClass("is-flipping");

    vi.advanceTimersByTime(650);

    expect(unit).not.toHaveClass("is-flipping");
    vi.useRealTimers();
  });

  it("clears pending flip timeout before update re-init", () => {
    vi.useFakeTimers();
    vi.setSystemTime(new Date("2026-07-24T00:00:00.000Z"));

    const { container } = render(
      <Countdown targetDate="2026-07-24T00:00:02.000Z" units={["seconds"]} />,
    );

    const countdownElement = container.querySelector("[data-countdown]");
    const countdown = CountdownStatic.getInstance(countdownElement);

    vi.advanceTimersByTime(1000);

    expect(container.querySelector(".countdown__unit")).toHaveClass(
      "is-flipping",
    );

    countdown?.update({
      targetDate: "2026-07-24T00:00:59.000Z",
      units: ["seconds"],
    });

    vi.advanceTimersByTime(650);

    expect(
      container.querySelector(".countdown__top .countdown__value")?.textContent,
    ).toBe("58");
    expect(container.querySelector(".countdown__unit")).not.toHaveClass(
      "is-flipping",
    );

    countdown?.destroy();
    vi.useRealTimers();
  });
});
