#!/usr/bin/env node

/**
 * Simple terminal chat client for Didactyl HTTP API.
 *
 * Usage:
 *   node didactyl-chat-cli.js
 *
 * Optional env vars:
 *   DIDACTYL_API_BASE_URL=http://127.0.0.1:8484
 *   DIDACTYL_MODEL=claude-haiku-4.5
 *   DIDACTYL_MAX_TURNS=4
 */

const readline = require("node:readline/promises");
const { stdin, stdout } = require("node:process");
const http = require("node:http");
const https = require("node:https");

const API_BASE_URL = process.env.DIDACTYL_API_BASE_URL || "https://127.0.0.1:8484";
const MODEL = process.env.DIDACTYL_MODEL || "";
const MAX_TURNS = Number.parseInt(process.env.DIDACTYL_MAX_TURNS || "4", 10);
const INSECURE_TLS = !["0", "false", "False", "FALSE"].includes(
  String(process.env.DIDACTYL_INSECURE_TLS || "1")
);

function printMessage(role, content) {
  const who = role === "user" ? "You" : role === "assistant" ? "Didactyl" : role;
  console.log(`${who}>`);
  console.log(content);
  console.log("");
}

function postJson(urlString, payload) {
  const url = new URL(urlString);
  const isHttps = url.protocol === "https:";
  const data = JSON.stringify(payload);

  const options = {
    method: "POST",
    hostname: url.hostname,
    port: url.port,
    path: url.pathname + url.search,
    headers: {
      "Content-Type": "application/json",
      "Content-Length": Buffer.byteLength(data),
    },
  };

  if (isHttps) {
    options.rejectUnauthorized = !INSECURE_TLS;
  }

  const client = isHttps ? https : http;

  return new Promise((resolve, reject) => {
    const req = client.request(options, (res) => {
      let body = "";
      res.setEncoding("utf8");
      res.on("data", (chunk) => {
        body += chunk;
      });
      res.on("end", () => {
        resolve({
          statusCode: res.statusCode || 0,
          body,
        });
      });
    });

    req.on("error", reject);
    req.write(data);
    req.end();
  });
}

async function callDidactyl(message) {
  const body = {
    message,
    max_turns: Number.isFinite(MAX_TURNS) ? MAX_TURNS : 4,
  };

  if (MODEL.trim()) {
    body.model = MODEL.trim();
  }

  const { statusCode, body: responseBody } = await postJson(`${API_BASE_URL}/api/prompt/agent`, body);

  if (statusCode < 200 || statusCode >= 300) {
    throw new Error(`HTTP ${statusCode}: ${responseBody}`);
  }

  let data;
  try {
    data = JSON.parse(responseBody);
  } catch {
    throw new Error(`Invalid JSON from API: ${responseBody}`);
  }

  if (!data.success) {
    throw new Error(data.error || "Didactyl API returned success=false");
  }

  return String(data.final_response || "");
}

async function main() {
  console.log("Didactyl CLI chat");
  console.log(`API: ${API_BASE_URL}`);
  console.log(`TLS verify: ${INSECURE_TLS ? "disabled (local dev)" : "enabled"}`);
  console.log("Type /exit to quit.\n");

  const rl = readline.createInterface({ input: stdin, output: stdout });

  try {
    while (true) {
      const input = (await rl.question("You> ")).trim();

      if (!input) {
        console.log("");
        continue;
      }

      if (input === "/exit" || input === "/quit") {
        console.log("Exiting.");
        break;
      }

      console.log("");

      try {
        const reply = await callDidactyl(input);
        printMessage("assistant", reply);
        console.log("");
      } catch (err) {
        const message = err instanceof Error ? err.message : String(err);
        console.error(`Didactyl error: ${message}`);
        console.error("");
      }
    }
  } finally {
    rl.close();
  }
}

main().catch((err) => {
  const message = err instanceof Error ? err.message : String(err);
  console.error(`Fatal error: ${message}`);
  process.exit(1);
});
