import { beforeEach, describe, expect, it, vi } from "vitest";
import { deleteEvaluatorProfile, importExportPayload, listEvaluatorProfiles, upsertEvaluatorNote } from "./evaluatorStorage";
import type { ExportPayload, 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()
  });
});

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",
  workplace: "Teststed",
  work_ability: 4,
  energy_level: 3,
  mental_clarity: 4,
  symptom_burden: 2,
  effort_strain: 3,
  status: "kan_fortsette",
  physical_energy: 3,
  mental_energy: 3,
  task_types: [],
  main_limitations: [],
  helpful_accommodations: []
};

function payload(reports: Report[]): ExportPayload {
  return {
    schema_version: 2,
    export_version: 2,
    exported_at: "2026-05-27T10:00:00.000Z",
    reports
  };
}

describe("evaluator-import", () => {
  it("importerer samme rapport-ID bare én gang", () => {
    const first = importExportPayload(JSON.stringify(payload([report])), "Person A");
    const second = importExportPayload(JSON.stringify(payload([report])), "Person A", first.profile.id);

    expect(first.added).toBe(1);
    expect(first.target_resolution).toBe("created_new_person");
    expect(second.added).toBe(0);
    expect(second.skipped).toBe(1);
    expect(second.target_resolution).toBe("matched_existing_person");
    expect(second.matched_person_id).toBe(first.profile.id);
    expect(second.matched_report_ids).toEqual(["rapport-1"]);
    expect(listEvaluatorProfiles()[0].reports).toHaveLength(1);
  });

  it("legger nye rapporter til eksisterende person ved UUID-treff", () => {
    const first = importExportPayload(JSON.stringify(payload([report])), "Person A");
    const nextReport = { ...report, id: "rapport-2", created_at: "2026-05-28T06:00:00.000Z", report_date: "2026-05-28" };
    const second = importExportPayload(JSON.stringify(payload([report, nextReport])), "Nytt navn som ikke skal overskrive");

    expect(second.added).toBe(1);
    expect(second.skipped).toBe(1);
    expect(second.target_resolution).toBe("matched_existing_person");
    expect(listEvaluatorProfiles()[0].reports).toHaveLength(2);
    expect(listEvaluatorProfiles()[0].display_name).toBe(first.profile.display_name);
  });

  it("oppretter ny bruker når ingen rapport-UUIDer matcher", () => {
    importExportPayload(JSON.stringify(payload([report])), "Person A");
    const unrelatedReport = { ...report, id: "rapport-ny", created_at: "2026-05-28T06:00:00.000Z", report_date: "2026-05-28" };
    const imported = importExportPayload(JSON.stringify(payload([unrelatedReport])), "Person B");

    expect(imported.target_resolution).toBe("created_new_person");
    expect(listEvaluatorProfiles()).toHaveLength(2);
  });

  it("stopper import når rapport-UUIDer matcher flere brukere", () => {
    const otherReport = { ...report, id: "rapport-2", created_at: "2026-05-28T06:00:00.000Z", report_date: "2026-05-28" };
    importExportPayload(JSON.stringify(payload([report])), "Person A");
    importExportPayload(JSON.stringify(payload([otherReport])), "Person B");

    expect(() => importExportPayload(JSON.stringify(payload([report, otherReport])), "Konflikt")).toThrow("matcher flere brukere");
  });

  it("beholder veiledernotater ved gjentatt import", () => {
    const first = importExportPayload(JSON.stringify(payload([report])), "Person A");
    upsertEvaluatorNote(first.profile.id, "Viktig rapportnotat", { note_type: "report", related_report_id: report.id });
    importExportPayload(JSON.stringify(payload([report])), "Person A", first.profile.id);

    const profile = listEvaluatorProfiles()[0];
    expect(profile.evaluator_notes).toHaveLength(1);
    expect(profile.evaluator_notes[0].text).toBe("Viktig rapportnotat");
  });

  it("sletter valgt veilederbruker uten å påvirke andre brukere", () => {
    const first = importExportPayload(JSON.stringify(payload([report])), "Person A");
    const otherReport = { ...report, id: "rapport-2", created_at: "2026-05-28T06:00:00.000Z", report_date: "2026-05-28" };
    const second = importExportPayload(JSON.stringify(payload([otherReport])), "Person B");
    upsertEvaluatorNote(first.profile.id, "Rapportnotat", { note_type: "report", related_report_id: report.id });

    deleteEvaluatorProfile(first.profile.id);

    const profiles = listEvaluatorProfiles();
    expect(profiles).toHaveLength(1);
    expect(profiles[0].id).toBe(second.profile.id);
    expect(profiles[0].reports).toHaveLength(1);
    expect(profiles[0].evaluator_notes).toHaveLength(0);
  });

  it("varsler og lagrer markering når import inneholder demodata", () => {
    const demoReport = { ...report, id: "demo-arbeidspuls-evaluator", demo: true };
    const result = importExportPayload(
      JSON.stringify({ ...payload([demoReport]), data_mode: "demo", contains_demo_data: true }),
      "Demo"
    );

    expect(result.demo_entries_detected).toBe(1);
    expect(result.profile.contains_demo_data).toBe(true);
    expect(listEvaluatorProfiles()[0].contains_demo_data).toBe(true);
  });

  it("holder veilederens demobrukere separat fra normale brukere", () => {
    const demoProfiles = listEvaluatorProfiles(true);

    expect(demoProfiles.length).toBeGreaterThanOrEqual(3);
    expect(demoProfiles.every((profile) => profile.contains_demo_data)).toBe(true);
    expect(listEvaluatorProfiles()).toHaveLength(0);
  });
});
