/**
 * Container and backend route handlers.
 *
 * Registers Hono routes for Docker container management and backend discovery.
 * Depends on the singleton {@link containerManager} for Docker operations.
 *
 * Routes:
 * - `GET /containers/status` — Check Docker availability and version.
 * - `GET /containers/images` — List available Docker images.
 * - `GET /backends` — List available backends (Claude Code, Codex) with binary detection.
 * - `GET /backends/:id/models` — List models for a backend (Codex reads from local cache).
 */

import type { Hono } from "hono";
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { homedir } from "node:os";
import { z } from "zod";
import { resolveBinary } from "../path-resolver.js";
import { containerManager } from "../container-manager.js";
import { parseParam } from "../validation.js";

// ─── Zod Schemas ──────────────────────────────────────────────────

const backendIdSchema = z.enum(["claude", "codex"]);

// ─── Routes ───────────────────────────────────────────────────────

export function registerContainerRoutes(api: Hono): void {
  api.get("/containers/status", async (c) => {
    const available = await containerManager.checkDocker();
    const version = available ? await containerManager.getDockerVersion() : null;
    return c.json({ available, version });
  });

  api.get("/containers/images", async (c) => {
    const images = await containerManager.listImages();
    return c.json(images);
  });

  // ─── Available backends ───────────────────────────────────────

  api.get("/backends", (c) => {
    const backends: Array<{ id: string; name: string; available: boolean }> = [];

    backends.push({ id: "claude", name: "Claude Code", available: resolveBinary("claude") !== null });
    backends.push({ id: "codex", name: "Codex", available: resolveBinary("codex") !== null });

    return c.json(backends);
  });

  api.get("/backends/:id/models", (c) => {
    const parsed = parseParam(c, "id", backendIdSchema);
    if (!parsed.success) return parsed.response;
    const backendId = parsed.data;

    if (backendId === "codex") {
      // Read Codex model list from its local cache file
      const cachePath = join(homedir(), ".codex", "models_cache.json");
      if (!existsSync(cachePath)) {
        return c.json({ error: "Codex models cache not found. Run codex once to populate it." }, 404);
      }
      try {
        const raw = readFileSync(cachePath, "utf-8");
        const cache = JSON.parse(raw) as {
          models: Array<{
            slug: string;
            display_name?: string;
            description?: string;
            visibility?: string;
            priority?: number;
          }>;
        };
        // Only return visible models, sorted by priority
        const models = cache.models
          .filter((m) => m.visibility === "list")
          .sort((a, b) => (a.priority ?? 99) - (b.priority ?? 99))
          .map((m) => ({
            value: m.slug,
            label: m.display_name || m.slug,
            description: m.description || "",
          }));
        return c.json(models);
      } catch (e) {
        return c.json({ error: "Failed to parse Codex models cache" }, 500);
      }
    }

    // Claude models are hardcoded on the frontend
    return c.json({ error: "Use frontend defaults for this backend" }, 404);
  });
}
