// server/publish.mjs — "Yayınla" pipeline: DB -> JSON files -> vite-ssg build -> dist swap
import fs from "node:fs";
import path from "node:path";
import { spawn } from "node:child_process";
import { fileURLToPath } from "node:url";
import { exportToFiles } from "./db.mjs";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const ROOT = path.resolve(__dirname, "..");
export const DIST_DIR = path.join(ROOT, "dist");
const STAGING_DIR = path.join(ROOT, ".dist-staging");
const LOG_LIMIT = 60_000;

const job = {
  running: false,
  startedAt: null,
  finishedAt: null,
  ok: null,
  log: "",
};

function append(text) {
  job.log = (job.log + text).slice(-LOG_LIMIT);
}

function run(cmd, args, opts = {}) {
  return new Promise((resolve, reject) => {
    const child = spawn(cmd, args, {
      cwd: ROOT,
      env: { ...process.env, ...opts.env },
      shell: false,
    });
    child.stdout.on("data", (d) => append(d.toString()));
    child.stderr.on("data", (d) => append(d.toString()));
    child.on("error", reject);
    child.on("close", (code) => {
      code === 0
        ? resolve()
        : reject(new Error(`${cmd} exited with code ${code}`));
    });
  });
}

export function getPublishState() {
  return { ...job };
}

// Kick off the publish pipeline in the background. Returns false if already running.
export function startPublish() {
  if (job.running) return false;
  job.running = true;
  job.ok = null;
  job.log = "";
  job.startedAt = new Date().toISOString();
  job.finishedAt = null;

  (async () => {
    try {
      append("[1/3] DB → JSON dosyaları aktarılıyor...\n");
      const written = await exportToFiles();
      append(`      ${written.length} dosya yazıldı\n`);

      append("[2/3] Site build ediliyor (vite-ssg)...\n");
      fs.rmSync(STAGING_DIR, { recursive: true, force: true });
      await run("npx", ["vite-ssg", "build"], {
        env: { BUILD_OUT_DIR: STAGING_DIR },
      });

      append("[3/3] dist güncelleniyor...\n");
      fs.rmSync(DIST_DIR, { recursive: true, force: true });
      fs.renameSync(STAGING_DIR, DIST_DIR);
      append("Tamamlandı ✓\n");
      job.ok = true;
    } catch (e) {
      append(`\nHATA: ${e.message}\n`);
      job.ok = false;
    } finally {
      job.running = false;
      job.finishedAt = new Date().toISOString();
    }
  })();

  return true;
}
