import { describe, it, expect, beforeEach, afterEach } from "vitest";
import fs from "fs";
import os from "os";
import path from "path";
import { NasFileManager } from "../services/nas-file-manager";

/**
 * Folder auto-creation primitive used by both the manual project-create path
 * (projects.service createProject) and the order→project paths (orders.service
 * createOrder / createOrderFromQuotation). Uses an isolated temp dir via the
 * constructor seam so it is deterministic and passes even where the real NAS
 * (Z:) is not mounted.
 */
describe("NasFileManager.createProjectFolder", () => {
  let tmpBase: string;
  let nas: NasFileManager;

  beforeEach(() => {
    tmpBase = fs.mkdtempSync(path.join(os.tmpdir(), "nas-proj-"));
    nas = new NasFileManager(tmpBase);
  });

  afterEach(() => {
    fs.rmSync(tmpBase, { recursive: true, force: true });
  });

  it("creates a <number>_<name> folder for a new project", () => {
    const ok = nas.createProjectFolder("26710001", "Rekonstrukce haly");
    expect(ok).toBe(true);
    expect(
      fs.existsSync(path.join(tmpBase, "26710001_Rekonstrukce_haly")),
    ).toBe(true);
  });

  it("is idempotent — a second call does not create a duplicate", () => {
    expect(nas.createProjectFolder("26710002", "Hala")).toBe(true);
    expect(nas.createProjectFolder("26710002", "Hala")).toBe(true);
    const matches = fs
      .readdirSync(tmpBase)
      .filter((e) => e.startsWith("26710002_"));
    expect(matches).toEqual(["26710002_Hala"]);
  });

  it("preserves Czech diacritics (no transliteration)", () => {
    expect(nas.createProjectFolder("26710003", "Měření haly")).toBe(true);
    expect(fs.existsSync(path.join(tmpBase, "26710003_Měření_haly"))).toBe(
      true,
    );
  });

  it("strips illegal characters and collapses spaces", () => {
    expect(nas.createProjectFolder("26710004", "A / B:  C")).toBe(true);
    expect(fs.existsSync(path.join(tmpBase, "26710004_A_B_C"))).toBe(true);
  });

  it("handles an empty name without crashing (trailing underscore)", () => {
    expect(nas.createProjectFolder("26710005", "")).toBe(true);
    expect(fs.existsSync(path.join(tmpBase, "26710005_"))).toBe(true);
  });

  it("returns false and creates nothing when the NAS base is not mounted", () => {
    const missing = new NasFileManager(
      path.join(tmpBase, "does-not-exist-subdir"),
    );
    expect(missing.createProjectFolder("26710006", "X")).toBe(false);
    expect(fs.existsSync(path.join(tmpBase, "does-not-exist-subdir"))).toBe(
      false,
    );
  });
});

/**
 * Folder deletion primitive used by the "delete folder" checkbox on both the
 * order delete (orders.service deleteOrder) and project delete (projects.service
 * deleteProject) paths. Matches the project by number prefix.
 */
describe("NasFileManager.deleteProjectFolder", () => {
  let tmpBase: string;
  let nas: NasFileManager;

  beforeEach(() => {
    tmpBase = fs.mkdtempSync(path.join(os.tmpdir(), "nas-del-"));
    nas = new NasFileManager(tmpBase);
  });

  afterEach(() => {
    fs.rmSync(tmpBase, { recursive: true, force: true });
  });

  it("removes an existing project folder (matched by number prefix)", async () => {
    nas.createProjectFolder("26710010", "Hala");
    expect(fs.existsSync(path.join(tmpBase, "26710010_Hala"))).toBe(true);
    const ok = await nas.deleteProjectFolder("26710010");
    expect(ok).toBe(true);
    expect(fs.existsSync(path.join(tmpBase, "26710010_Hala"))).toBe(false);
  });

  it("is a no-op (returns true) when no folder exists for the number", async () => {
    expect(await nas.deleteProjectFolder("26710011")).toBe(true);
  });

  it("returns false when the NAS base is not mounted", async () => {
    const missing = new NasFileManager(path.join(tmpBase, "nope"));
    expect(await missing.deleteProjectFolder("26710012")).toBe(false);
  });
});
