import { randomUUID } from "node:crypto";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { getConfig, shouldNotify } from "./config.ts";
import { getNotificationBackend, sendNotification } from "./terminal.ts";
import type { NotifyConfig } from "./types.ts";

type ExtensionDependencies = {
  now: () => number;
  createNotificationId: () => string;
  notify: (config: NotifyConfig) => void;
  getBackend: typeof getNotificationBackend;
};

export function createPiNotifyExtension(dependencies: Partial<ExtensionDependencies> = {}) {
  const now = dependencies.now ?? Date.now;
  const createNotificationId = dependencies.createNotificationId ?? (() => `pi-${process.pid}-${randomUUID()}`);
  const notify = dependencies.notify ?? sendNotification;
  const getBackend = dependencies.getBackend ?? getNotificationBackend;

  return function piNotify(pi: ExtensionAPI): void {
    const notificationId = createNotificationId();
    let startedAt: number | undefined;
    let latestMessages: unknown[] | undefined;
    let toolErrorCount = 0;
    let enabledOverride: boolean | undefined;

    const resetRun = (): void => {
      startedAt = undefined;
      latestMessages = undefined;
      toolErrorCount = 0;
    };

    pi.on("agent_start", () => {
      startedAt ??= now();
    });

    pi.on("tool_execution_end", (event) => {
      if (event.isError) toolErrorCount++;
    });

    pi.on("agent_end", (event) => {
      latestMessages = event.messages;
    });

    pi.on("agent_settled", (_event, ctx) => {
      try {
        const config = getConfig(ctx, startedAt, latestMessages, { notificationId, toolErrorCount }, now());
        if (ctx.mode === "tui" && shouldNotify(config, enabledOverride)) notify(config);
      } finally {
        resetRun();
      }
    });

    pi.registerCommand("notify", {
      description: "Control Kitty/macOS completion notifications: on, off, test, status",
      handler: async (args, ctx) => {
        const action = args.trim().toLowerCase() || "status";

        if (action === "on" || action === "off") {
          enabledOverride = action === "on";
          ctx.ui.notify(`Completion notifications ${action}`, "info");
          return;
        }

        const config = getConfig(ctx, now() - 1000, undefined, { notificationId, toolErrorCount: 0 }, now());
        if (action === "test") {
          if (ctx.mode !== "tui") {
            ctx.ui.notify("System notifications are only emitted in interactive TUI mode", "warning");
            return;
          }
          notify({ ...config, enabled: true, minDurationMs: 0, body: "Kitty notification test — click to focus this window" });
          ctx.ui.notify(`Test sent through ${getBackend()}`, "info");
          return;
        }

        if (action === "status") {
          const enabled = enabledOverride ?? config.enabled;
          ctx.ui.notify(
            `Notifications ${enabled ? "on" : "off"} · ${getBackend()} · ${config.visibility} · min ${config.minDurationMs / 1000}s`,
            "info",
          );
          return;
        }

        ctx.ui.notify("Usage: /notify on|off|test|status", "warning");
      },
    });
  };
}

export default createPiNotifyExtension();
