import { installClaude } from "../../install/claude.ts";
import { installOpencode } from "../../install/opencode.ts";
import { installCline } from "../../install/cline.ts";
import { installAider } from "../../install/aider.ts";
import { loadGlobalConfig } from "../../lifecycle/config.ts";
import { paths } from "../../lifecycle/paths.ts";
import type { InstallContext, InstallResult } from "../../install/types.ts";

// DO NOT add `claude` back as an active installer — see CLAUDE.md
// "no-global-settings-injection". `installClaude` already returns a refusal
// pointing users at the `cld` wrapper; keeping it in TARGETS preserves the
// loud error path for anyone who still runs `fewtok install claude`.
const TARGETS: Record<string, (ctx: InstallContext) => InstallResult> = {
  claude: installClaude,
  opencode: installOpencode,
  cline: installCline,
  aider: installAider,
};

export async function cmdInstall(
  args: { positional: string[]; flags: Record<string, string | true> },
  verbose = false
): Promise<number> {
  const cfg = loadGlobalConfig();
  if (typeof cfg.port !== "number" || cfg.port <= 0) {
    console.error("fewtok port not pinned. Run `fewtok init` first.");
    return 1;
  }
  const ctx: InstallContext = { port: cfg.port, home: paths.home() };
  const targets = args.flags.all ? Object.keys(TARGETS) : args.positional;
  if (targets.length === 0) {
    console.error("usage: fewtok install <claude|opencode|cline|aider> [...] | --all");
    return 1;
  }
  const results: Array<{ ok: boolean; message: string; path: string }> = [];
  for (const t of targets) {
    const fn = TARGETS[t];
    if (!fn) {
      console.error(`unknown install target: ${t}`);
      results.push({ ok: false, message: `unknown install target: ${t}`, path: t });
      continue;
    }
    try {
      const r = fn(ctx);
      results.push(r);
    } catch (e) {
      results.push({ ok: false, message: (e as Error).message, path: t });
    }
  }

  if (!verbose) {
    const parts = results.map((r) => `${r.ok ? "ok" : "err"}=${r.path}`);
    console.log(parts.join(" "));
    return results.every((r) => r.ok) ? 0 : 1;
  }

  for (const r of results) {
    console.log(`${r.ok ? "✓" : "✗"} ${r.message}  [${r.path}]`);
  }
  return results.every((r) => r.ok) ? 0 : 1;
}
