import { describe, expect, test } from "vitest";
import { DEFAULT_QUERY, dashboardHref, parseDashboardQuery } from "@/lib/dashboard-query";
import { formatDate, formatDateTime, formatElapsed, formatResponseTime } from "@/lib/format";
import { displayStatus, isUp } from "@/lib/status";

describe("displayStatus", () => {
  test("disabled always wins, even over a failing last result", () => {
    expect(displayStatus({ monitoringEnabled: false, currentStatus: "NOT_WORKING" })).toBe("DISABLED");
    expect(displayStatus({ monitoringEnabled: false, currentStatus: null })).toBe("DISABLED");
  });
  test("enabled apps show their latest result, or pending before the first check", () => {
    expect(displayStatus({ monitoringEnabled: true, currentStatus: "WORKING" })).toBe("WORKING");
    expect(displayStatus({ monitoringEnabled: true, currentStatus: "SLOW" })).toBe("SLOW");
    expect(displayStatus({ monitoringEnabled: true, currentStatus: "NOT_WORKING" })).toBe("NOT_WORKING");
    expect(displayStatus({ monitoringEnabled: true, currentStatus: null })).toBe("PENDING");
  });
  test("Working and Slow are both 'up'", () => {
    expect(isUp("WORKING")).toBe(true);
    expect(isUp("SLOW")).toBe(true);
    expect(isUp("NOT_WORKING")).toBe(false);
  });
});

describe("dashboard query", () => {
  test("defaults", () => {
    expect(parseDashboardQuery({})).toEqual(DEFAULT_QUERY);
  });
  test("hostile or malformed params fall back to safe defaults", () => {
    expect(
      parseDashboardQuery({ status: "nope", sort: "id;drop table projects--", dir: "sideways", page: "-5", q: ["a", "b"] }),
    ).toEqual({ ...DEFAULT_QUERY, q: "a" });
  });
  test("round-trips through hrefs and leaves defaults out of the URL", () => {
    const query = parseDashboardQuery({ status: "not-working", q: "line", sort: "responseTime", dir: "desc", page: "2" });
    expect(query).toEqual({ status: "NOT_WORKING", q: "line", sort: "responseTime", dir: "desc", page: 2 });
    expect(dashboardHref(query)).toBe("/?status=not-working&q=line&sort=responseTime&dir=desc&page=2");
    expect(dashboardHref(DEFAULT_QUERY)).toBe("/");
    expect(dashboardHref(query, { status: null, page: 1 })).toBe("/?q=line&sort=responseTime&dir=desc");
    expect(dashboardHref(DEFAULT_QUERY, { status: "SLOW" })).toBe("/?status=slow");
    expect(parseDashboardQuery({ status: "slow" }).status).toBe("SLOW");
  });
});

describe("formatting", () => {
  const instant = new Date("2026-09-17T03:30:00Z");
  test("dates render in the given timezone with a stable format", () => {
    expect(formatDateTime(instant, "Asia/Kolkata")).toBe("17 Sep 2026, 09:00 AM");
    expect(formatDateTime(instant, "UTC")).toBe("17 Sep 2026, 03:30 AM");
    expect(formatDateTime(new Date("2026-09-17T18:45:00Z"), "Asia/Kolkata")).toBe("18 Sep 2026, 12:15 AM");
    expect(formatDate(instant, "Asia/Kolkata")).toBe("17 Sep 2026");
  });
  test("response time and elapsed time", () => {
    expect(formatResponseTime(184)).toBe("184 ms");
    expect(formatResponseTime(1243)).toBe("1,243 ms");
    const from = new Date("2026-09-15T03:30:00Z");
    expect(formatElapsed(from, new Date("2026-09-15T03:30:20Z"))).toBe("just now");
    expect(formatElapsed(from, new Date("2026-09-15T04:31:00Z"))).toBe("1 hour");
    expect(formatElapsed(from, new Date("2026-09-17T09:00:00Z"))).toBe("2 days");
  });
});
