/**
 * Helpers for pi 0.80+ ModelRuntime / ModelRegistry.
 *
 * AuthStorage is no longer exported from @earendil-works/pi-coding-agent package
 * root (exports only "." and "./rpc-entry"). We use ModelRuntime for registry
 * access, and read/write ~/.pi/agent/auth.json directly for API-key CRUD so
 * Next.js bundling never needs a forbidden subpath import.
 */
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { dirname, join } from "node:path";
import {
  ModelRegistry,
  ModelRuntime,
  SettingsManager,
  getAgentDir,
} from "@earendil-works/pi-coding-agent";

export type StoredCredential =
  | { type: "api_key"; key: string; env?: Record<string, string> }
  | { type: "oauth"; [key: string]: unknown };

type AuthFile = Record<string, StoredCredential>;

function authJsonPath(authPath?: string): string {
  return authPath ?? join(getAgentDir(), "auth.json");
}

function readAuthFile(path: string): AuthFile {
  try {
    if (!existsSync(path)) return {};
    const raw = readFileSync(path, "utf8");
    if (!raw.trim()) return {};
    const data = JSON.parse(raw) as unknown;
    if (!data || typeof data !== "object" || Array.isArray(data)) return {};
    return data as AuthFile;
  } catch {
    return {};
  }
}

function writeAuthFile(path: string, data: AuthFile): void {
  mkdirSync(dirname(path), { recursive: true });
  writeFileSync(path, JSON.stringify(data, null, 2) + "\n", "utf8");
}

/** Persist an API key to auth.json (same shape as pi AuthStorage). */
export function setStoredApiKey(provider: string, apiKey: string, authPath?: string): void {
  const path = authJsonPath(authPath);
  const data = readAuthFile(path);
  data[provider] = { type: "api_key", key: apiKey };
  writeAuthFile(path, data);
}

/** Remove a provider credential from auth.json. */
export function removeStoredCredential(provider: string, authPath?: string): void {
  const path = authJsonPath(authPath);
  const data = readAuthFile(path);
  if (!(provider in data)) return;
  delete data[provider];
  writeAuthFile(path, data);
}

export async function createModelStack(opts?: {
  modelsPath?: string | null;
  authPath?: string;
}) {
  const runtime = await ModelRuntime.create({
    authPath: opts?.authPath,
    modelsPath: opts?.modelsPath,
  });
  const registry = new ModelRegistry(runtime);
  await registry.refresh();
  return { runtime, registry };
}

export function getSettings() {
  const agentDir = getAgentDir();
  return SettingsManager.create(process.cwd(), agentDir);
}

export { ModelRegistry, ModelRuntime, SettingsManager, getAgentDir };
