import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, expect, test, vi } from "vitest";
import {
    TimeRangeFilter,
    datetimeTextToMs,
    formatRangeDistance,
    normalizeRange,
    timeRangeLabel,
} from "@/shared/ui/TimeRangeFilter.jsx";

describe("TimeRangeFilter helpers", () => {
    test("parses strict local date time text", () => {
        const ms = datetimeTextToMs("2026-05-13 12:30");
        const date = new Date(ms);

        expect(date.getFullYear()).toBe(2026);
        expect(date.getMonth()).toBe(4);
        expect(date.getDate()).toBe(13);
        expect(date.getHours()).toBe(12);
        expect(date.getMinutes()).toBe(30);
        expect(datetimeTextToMs("2026-13-13 12:30")).toBeNull();
        expect(datetimeTextToMs("")).toBe("");
    });

    test("keeps range as a single display label", () => {
        const startMs = datetimeTextToMs("2026-05-13 10:00");
        const endMs = datetimeTextToMs("2026-05-13 12:00");

        expect(normalizeRange({ endMs, startMs })).toEqual({ endMs, startMs });
        expect(timeRangeLabel("时间", { endMs, startMs })).toContain(" - ");
        expect(timeRangeLabel("时间", {})).toBe("时间");
    });

    test("formats the selected interval for timed and date-only ranges", () => {
        const startMs = datetimeTextToMs("2026-05-13 10:00");
        const endMs = datetimeTextToMs("2026-05-14 12:30");

        expect(formatRangeDistance(startMs, endMs)).toBe("间隔 1 天 2 小时 30 分钟");
        expect(formatRangeDistance(startMs, endMs, false)).toBe("间隔 1 天");
        expect(formatRangeDistance(startMs, "")).toBe("选择完整区间");
    });

    test("switches to the end field after choosing a start date and marks the whole range", async () => {
        const user = userEvent.setup();
        const startMs = datetimeTextToMs("2026-05-13 10:00");
        const endMs = datetimeTextToMs("2026-05-16 12:00");

        render(<TimeRangeFilter label="活动时间" value={{ endMs, startMs }} onChange={vi.fn()} />);

        await user.click(screen.getByRole("button", { name: /活动时间/ }));
        await user.click(screen.getByRole("button", { name: "14" }));

        expect(screen.getByRole("button", { name: /结束时间/ }).className).toContain("rangeFieldActive");
        expect(screen.getByText("间隔 2 天 2 小时")).toBeInTheDocument();
        expect(screen.getByRole("button", { name: "14" })).toHaveAttribute("data-range-edge", "始");
        expect(screen.getByRole("button", { name: "15" }).className).toContain("dayInRange");
        expect(screen.getByRole("button", { name: "16" })).toHaveAttribute("data-range-edge", "末");
    });

    test("date-only mode hides time controls and returns day boundaries", async () => {
        const user = userEvent.setup();
        const onChange = vi.fn();
        const startMs = datetimeTextToMs("2026-05-13 00:00");
        const endMs = datetimeTextToMs("2026-05-20 23:59");

        render(<TimeRangeFilter label="自定义区间" value={{ endMs, startMs }} withTime={false} onChange={onChange} />);

        await user.click(screen.getByRole("button", { name: /自定义区间/ }));

        expect(screen.queryByLabelText("时")).toBeNull();
        expect(screen.queryByRole("button", { name: "近 24 小时" })).toBeNull();

        await user.click(screen.getByRole("button", { name: /结束日期/ }));
        await user.click(screen.getByRole("button", { name: "21" }));
        await user.click(screen.getByRole("button", { name: "确定" }));

        const next = onChange.mock.calls[0][0];
        const end = new Date(next.endMs);
        expect(next.startMs).toBe(startMs);
        expect(end.getFullYear()).toBe(2026);
        expect(end.getMonth()).toBe(4);
        expect(end.getDate()).toBe(21);
        expect(end.getHours()).toBe(23);
        expect(end.getMinutes()).toBe(59);
    });

    test("confirms picker changes without submitting an outer form", async () => {
        const user = userEvent.setup();
        const onChange = vi.fn();
        const onSubmit = vi.fn((event) => event.preventDefault());
        const startMs = datetimeTextToMs("2026-05-13 10:00");
        const endMs = datetimeTextToMs("2026-05-13 12:00");

        render(
            <form onSubmit={onSubmit}>
                <TimeRangeFilter label="活动时间" value={{ endMs, startMs }} onChange={onChange} />
            </form>,
        );

        await user.click(screen.getByRole("button", { name: /活动时间/ }));
        await user.click(screen.getByRole("button", { name: "确定" }));

        expect(onChange).toHaveBeenCalledWith({ endMs, startMs });
        expect(onSubmit).not.toHaveBeenCalled();
    });
});
