import assert from "node:assert/strict";
import { afterEach, describe, it } from "node:test";
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
import { getConfig, shouldNotify } from "../src/config.ts";

const envKeys = [
  "PI_NOTIFY_ENABLED",
  "PI_NOTIFY_TITLE",
  "PI_NOTIFY_BODY",
  "PI_NOTIFY_MESSAGE_SOURCE",
  "PI_NOTIFY_MESSAGE_MAX",
  "PI_NOTIFY_MIN_SECONDS",
  "PI_NOTIFY_VISIBILITY",
  "PI_NOTIFY_ACTION",
  "PI_NOTIFY_SOUND_CMD",
] as const;

const savedEnv = new Map(envKeys.map((key) => [key, process.env[key]]));

afterEach(() => {
  for (const key of envKeys) {
    const value = savedEnv.get(key);
    if (value === undefined) delete process.env[key];
    else process.env[key] = value;
  }
});

function context(): ExtensionContext {
  return {
    cwd: "/tmp/pi-notify",
    model: { provider: "openai", id: "gpt-4.1" },
  } as ExtensionContext;
}

const runtime = { notificationId: "pi-session", toolErrorCount: 0 };

describe("config", () => {
  it("builds safe Kitty defaults from the settled assistant output", () => {
    const config = getConfig(
      context(),
      800,
      [
        { role: "user", content: "please fix this" },
        { role: "assistant", content: "fixed it" },
      ],
      runtime,
      5_000,
    );

    assert.deepEqual(config, {
      enabled: true,
      title: "π - pi-notify",
      body: "fixed it",
      durationMs: 4_200,
      minDurationMs: 3_000,
      notificationId: "pi-session",
      visibility: "always",
      action: "focus",
      soundCommand: undefined,
    });
    assert.equal(shouldNotify(config), true);
  });

  it("supports privacy, threshold, focus, and status template settings", () => {
    process.env.PI_NOTIFY_ENABLED = "off";
    process.env.PI_NOTIFY_TITLE = "{status_icon} {status} {tool_error_count}";
    process.env.PI_NOTIFY_BODY = "{message}";
    process.env.PI_NOTIFY_MESSAGE_SOURCE = "none";
    process.env.PI_NOTIFY_MIN_SECONDS = "10.5";
    process.env.PI_NOTIFY_VISIBILITY = "invisible";
    process.env.PI_NOTIFY_ACTION = "none";
    process.env.PI_NOTIFY_SOUND_CMD = " say done ";

    const config = getConfig(context(), 1_000, [{ role: "assistant", content: "secret" }], {
      notificationId: "pi-session",
      toolErrorCount: 2,
    }, 2_000);

    assert.equal(config.title, "⚠ ready · 2 tool errors 2");
    assert.equal(config.body, "Ready for input");
    assert.equal(config.enabled, false);
    assert.equal(config.minDurationMs, 10_500);
    assert.equal(config.visibility, "invisible");
    assert.equal(config.action, "none");
    assert.equal(config.soundCommand, "say done");
    assert.equal(shouldNotify(config), false);
    assert.equal(shouldNotify(config, true), false, "the minimum duration still applies to command overrides");
  });

  it("applies selected-message truncation and a session override", () => {
    process.env.PI_NOTIFY_MESSAGE_SOURCE = "user";
    process.env.PI_NOTIFY_MESSAGE_MAX = "5";
    process.env.PI_NOTIFY_MIN_SECONDS = "0";
    const config = getConfig(
      context(),
      1_000,
      [{ role: "user", content: "hello world" }],
      runtime,
      2_000,
    );

    assert.equal(config.body, "hell…");
    assert.equal(shouldNotify(config, false), false);
    assert.equal(shouldNotify(config, true), true);
  });
});
