// server/db.mjs — Postgres pool + schema bootstrap + file seed
import pg from "pg";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
export const DATA_DIR = path.resolve(__dirname, "../src/data");

export const pool = new pg.Pool({
  connectionString: process.env.DATABASE_URL,
  max: 5,
  connectionTimeoutMillis: 10000,
});

const SLUG_RE = /^[a-z0-9-]+$/;

export function isValidSlug(s) {
  return typeof s === "string" && SLUG_RE.test(s);
}

// Read all src/data/<page>/<locale>.json files
export function readDataFiles() {
  const out = [];
  for (const page of fs.readdirSync(DATA_DIR)) {
    const dir = path.join(DATA_DIR, page);
    if (!fs.statSync(dir).isDirectory()) continue;
    for (const file of fs.readdirSync(dir)) {
      if (!file.endsWith(".json")) continue;
      const locale = file.replace(/\.json$/, "");
      if (!isValidSlug(page) || !isValidSlug(locale)) continue;
      const raw = fs.readFileSync(path.join(dir, file), "utf-8");
      out.push({ page, locale, content: JSON.parse(raw) });
    }
  }
  return out;
}

export async function ensureSchema() {
  await pool.query(`
    CREATE TABLE IF NOT EXISTS page_data (
      id SERIAL PRIMARY KEY,
      page TEXT NOT NULL,
      locale TEXT NOT NULL,
      content JSONB NOT NULL,
      updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
      UNIQUE (page, locale)
    )
  `);
}

// Seed DB from JSON files. overwrite=false keeps existing DB rows intact.
export async function seedFromFiles({ overwrite = false } = {}) {
  const files = readDataFiles();
  let inserted = 0;
  for (const { page, locale, content } of files) {
    const res = await pool.query(
      overwrite
        ? `INSERT INTO page_data (page, locale, content, updated_at)
           VALUES ($1, $2, $3, now())
           ON CONFLICT (page, locale)
           DO UPDATE SET content = EXCLUDED.content, updated_at = now()`
        : `INSERT INTO page_data (page, locale, content)
           VALUES ($1, $2, $3)
           ON CONFLICT (page, locale) DO NOTHING`,
      [page, locale, JSON.stringify(content)],
    );
    inserted += res.rowCount;
  }
  return { total: files.length, written: inserted };
}

// Write DB rows back to src/data/<page>/<locale>.json
// Formatted with Prettier so exports match the repo's existing JSON style.
export async function exportToFiles() {
  const prettier = await import("prettier");
  const { rows } = await pool.query(
    "SELECT page, locale, content FROM page_data ORDER BY page, locale",
  );
  const written = [];
  for (const { page, locale, content } of rows) {
    if (!isValidSlug(page) || !isValidSlug(locale)) continue;
    const dir = path.join(DATA_DIR, page);
    fs.mkdirSync(dir, { recursive: true });
    const formatted = await prettier.format(JSON.stringify(content), {
      parser: "json",
    });
    fs.writeFileSync(path.join(dir, `${locale}.json`), formatted, "utf-8");
    written.push(`${page}/${locale}.json`);
  }
  return written;
}
