import { beforeEach, describe, expect, it, vi } from "vitest";
import { buildFollowupResponsePoints, buildWorkTimeBands, calculateFollowupEffectScore, createLineSegments, formatDateTime, graphDomainStart } from "./App";
import { datePlaceholderForLanguage } from "./i18n";
import type { DelayedFollowup, Report } from "./types";

const store = new Map<string, string>();

beforeEach(() => {
  store.clear();
  vi.stubGlobal("localStorage", {
    getItem: (key: string) => store.get(key) ?? null,
    setItem: (key: string, value: string) => store.set(key, value),
    removeItem: (key: string) => store.delete(key),
    clear: () => store.clear()
  });
});

describe("grafsegmenter", () => {
  it("lager striplet horisontal startlinje og stripler hull på minst tre dager", () => {
    const day = 24 * 60 * 60 * 1000;
    const segments = createLineSegments(
      [
        { x: 20, y: 50, time: 0 },
        { x: 40, y: 40, time: day },
        { x: 100, y: 20, time: 4 * day }
      ],
      0
    );

    expect(segments[0]).toMatchObject({ x1: 0, x2: 20, y1: 50, y2: 50, dashed: true });
    expect(segments[1].dashed).toBe(false);
    expect(segments[2].dashed).toBe(true);
    expect(segments[2]).toMatchObject({ x1: 40, y1: 40, x2: 100, y2: 20 });
  });
});

describe("oppfølgingsrespons", () => {
  const report: Report = {
    id: "rapport-1",
    report_time: "08:00:00",
    report_date: "2026-05-27",
    created_at: "2026-05-27T06:00:00.000Z",
    type: "work_report",
    work_ability: 4,
    energy_level: 4,
    mental_clarity: 4,
    symptom_burden: 2,
    effort_strain: 2,
    status: "kan_fortsette",
    physical_energy: 4,
    mental_energy: 4,
    total_score_percent: 80,
    task_types: [],
    main_limitations: [],
    helpful_accommodations: []
  };

  const followup: DelayedFollowup = {
    id: "oppfolging-1",
    report_time: "10:00:00",
    report_date: "2026-05-28",
    created_at: "2026-05-28T08:00:00.000Z",
    type: "delayed_followup",
    parent_report_id: "rapport-1",
    worse_than_before: "mye",
    delayed_symptoms: [],
    recovery_status: "ikke_tilbake_til_baseline"
  };

  it("beregner visualisert ettereffekt uten å endre parent-score", () => {
    expect(calculateFollowupEffectScore(80, "mye", "ikke_tilbake_til_baseline")).toBe(30);
    expect(calculateFollowupEffectScore(80, "nei", "tilbake_til_baseline")).toBe(85);
  });

  it("lager responsmodell på faktisk oppfølgingstidspunkt med parent-kobling", () => {
    const [point] = buildFollowupResponsePoints([report, followup]);

    expect(point.parent.id).toBe("rapport-1");
    expect(point.followup.id).toBe("oppfolging-1");
    expect(point.parentScore).toBe(80);
    expect(point.effectScore).toBe(30);
    expect(point.offsetHours).toBe(26);
  });

  it("bruker engelsk ukedag når språk er engelsk", () => {
    localStorage.setItem("arbeidspuls.language", "en");

    expect(formatDateTime(report)).toContain("Wednesday");

    localStorage.setItem("arbeidspuls.language", "nb-NO");
    expect(formatDateTime(report)).toContain("Onsdag");
  });

  it("bruker ukrainsk ukedag når språk er ukrainsk", () => {
    localStorage.setItem("arbeidspuls.language", "uk-UA");

    expect(formatDateTime(report)).toContain("Середа");
  });

  it("lager arbeidstidsband og håndterer arbeidstid over midnatt", () => {
    const daytime = { ...report, id: "rapport-dag", work_start_time: "08:00", work_end_time: "10:00" };
    const overnight = { ...report, id: "rapport-natt", work_start_time: "23:00", work_end_time: "01:00" };
    const missing = { ...report, id: "rapport-uten", work_start_time: undefined, work_end_time: "12:00" };

    const bands = buildWorkTimeBands([daytime, overnight, missing]);

    expect(bands).toHaveLength(2);
    expect(bands[0].reportId).toBe("rapport-dag");
    expect(bands[0].endAt - bands[0].startAt).toBe(2 * 60 * 60 * 1000);
    expect(bands[1].reportId).toBe("rapport-natt");
    expect(bands[1].endAt - bands[1].startAt).toBe(2 * 60 * 60 * 1000);
  });

  it("har språktilpassede datoplaceholdere for graffilter", () => {
    expect(datePlaceholderForLanguage("nb-NO")).toBe("dd/mm/åååå");
    expect(datePlaceholderForLanguage("en")).toBe("dd/mm/yyyy");
    expect(datePlaceholderForLanguage("uk-UA")).toBe("дд/мм/рррр");
  });

  it("runder grafstart ned til 00:00 på første synlige dato", () => {
    const pointTime = new Date("2026-05-27T11:00:00").getTime();
    const domainStart = graphDomainStart([pointTime]);
    const startDate = new Date(domainStart);

    expect(startDate.getHours()).toBe(0);
    expect(startDate.getMinutes()).toBe(0);
    expect(startDate.getFullYear()).toBe(2026);
    expect(startDate.getMonth()).toBe(4);
    expect(startDate.getDate()).toBe(27);
  });
});
