#!/usr/bin/env node
/**
 * Pull postgres external URL from Coolify API and write DATABASE_URL + POSTGRES_URL in .env.local.
 *
 * Loads (in order): ../.coolify.env, .env, .env.local (Coolify wins for COOLIFY_* from parent file).
 *
 * Identify DB by (first match):
 *   COOLIFY_DATABASE_UUID  — exact
 *   COOLIFY_DATABASE_NAME  — default: vibn-postgres
 *   argv[2]                — uuid or name substring
 *
 * Requires: COOLIFY_URL, COOLIFY_API_TOKEN
 */
import { config } from "dotenv";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";

const root = path.join(path.dirname(fileURLToPath(import.meta.url)), "..");
const repoRoot = path.join(root, "..");

config({ path: path.join(repoRoot, ".coolify.env") });
config({ path: path.join(root, ".env") });
config({ path: path.join(root, ".env.local"), override: true });

const COOLIFY_URL = (process.env.COOLIFY_URL ?? "").replace(/\/$/, "");
const token = process.env.COOLIFY_API_TOKEN ?? "";
const arg = process.argv[2];

function fail(msg) {
  console.error(msg);
  process.exit(1);
}

if (!COOLIFY_URL || !token) {
  fail("Missing COOLIFY_URL or COOLIFY_API_TOKEN (e.g. set in master-ai/.coolify.env).");
}

function normalizeDatabaseUrl(url) {
  if (!url || typeof url !== "string") return "";
  return url.replace(/^postgres:\/\//i, "postgresql://");
}

async function coolifyFetch(path) {
  const res = await fetch(`${COOLIFY_URL}/api/v1${path}`, {
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
    },
  });
  if (!res.ok) {
    const text = await res.text();
    fail(`Coolify API ${res.status} ${path}: ${text.slice(0, 500)}`);
  }
  return res.json();
}

function pickDatabase(list) {
  const uuid = process.env.COOLIFY_DATABASE_UUID?.trim();
  const nameDefault = process.env.COOLIFY_DATABASE_NAME || "vibn-postgres";

  if (uuid) {
    const d = list.find((x) => x.uuid === uuid);
    if (d) return d;
    fail(`No database with COOLIFY_DATABASE_UUID=${uuid}.`);
  }

  if (arg?.trim()) {
    const a = arg.trim().toLowerCase();
    const byUuid = list.find((x) => x.uuid === arg.trim());
    if (byUuid) return byUuid;
    const byName = list.find(
      (x) =>
        String(x.name ?? "")
          .toLowerCase()
          .includes(a) ||
        String(x.uuid ?? "")
          .toLowerCase()
          .includes(a)
    );
    if (byName) return byName;
    fail(`No database matching "${arg}".`);
  }

  const byName = list.find(
    (x) => String(x.name ?? "").toLowerCase() === nameDefault.toLowerCase()
  );
  if (byName) return byName;

  fail(
    `No database named "${nameDefault}". Set COOLIFY_DATABASE_UUID or pass uuid/name as argument.`
  );
}

async function main() {
  const list = await coolifyFetch("/databases");
  if (!Array.isArray(list) || list.length === 0) {
    fail("Coolify returned no databases.");
  }

  const picked = pickDatabase(list);
  const detail = await coolifyFetch(`/databases/${picked.uuid}`);
  const raw = detail.external_db_url;
  const databaseUrl = normalizeDatabaseUrl(raw);

  if (!databaseUrl) {
    fail(
      "No external_db_url from Coolify. Enable public exposure and set a host port on the Postgres service, then restart."
    );
  }

  const envLocalPath = path.join(root, ".env.local");
  if (!fs.existsSync(envLocalPath)) {
    fail(`Missing ${envLocalPath}; create it first (copy from .env.example).`);
  }

  let body = fs.readFileSync(envLocalPath, "utf8");
  const lines = body.split(/\r?\n/);
  const setLine = (key, value) => {
    const next = `${key}=${value}`;
    let seen = false;
    for (let i = 0; i < lines.length; i++) {
      if (lines[i].startsWith(`${key}=`)) {
        lines[i] = next;
        seen = true;
        break;
      }
    }
    if (!seen) lines.push(next);
  };

  setLine("DATABASE_URL", databaseUrl);
  setLine("POSTGRES_URL", databaseUrl);

  fs.writeFileSync(envLocalPath, lines.join("\n") + (body.endsWith("\n") ? "\n" : ""), "utf8");
  console.log(
    `Updated DATABASE_URL and POSTGRES_URL in .env.local from Coolify (${picked.name}, ${picked.uuid}).`
  );
  console.log(`Public port from API: ${detail.public_port ?? "(n/a)"}; is_public: ${detail.is_public ?? "(n/a)"}`);
}

main().catch((e) => {
  console.error(e);
  process.exit(1);
});
