"use strict";
const express = require("express");
const cookieParser = require("cookie-parser");
const cors = require("cors");
const path = require("path");
const fs = require("fs");

// Load config (written by install wizard)
let dbConfig = null;
const configPath = path.join(__dirname, "config.json");
if (fs.existsSync(configPath)) {
  try { dbConfig = JSON.parse(fs.readFileSync(configPath, "utf8")); } catch (_) {}
}

// Provide DB config to routes via global (simple approach for cPanel)
global.DB_CONFIG = dbConfig ?? {
  host: process.env.DB_HOST || "localhost",
  port: parseInt(process.env.DB_PORT || "3306"),
  user: process.env.DB_USER || "rbnbtcii_projec5",
  password: process.env.DB_PASS || "$Adeniyi12425",
  database: process.env.DB_NAME || "rbnbtcii_project5",
};

const { ensureSeed } = require("./api/seed");
const router = require("./api/routes");

const app = express();
app.use(cookieParser());
app.use(express.json({ limit: "20mb" }));
app.use(express.urlencoded({ extended: true, limit: "20mb" }));
app.use(cors({ origin: true, credentials: true }));

// Serve install wizard if not yet configured
app.use("/install", express.static(path.join(__dirname, "install")));

// Install wizard API — must be before the main router
const mysql = require("mysql2/promise");
app.post("/api/install/test-db", async (req, res) => {
  const cfg = req.body;
  if (!cfg || !cfg.database || !cfg.user) return res.status(400).json({ ok: false, error: "Missing fields" });
  try {
    const conn = await mysql.createConnection({ host: cfg.host, port: cfg.port || 3306, user: cfg.user, password: cfg.password, database: cfg.database, connectTimeout: 8000 });
    await conn.ping();
    await conn.end();
    res.json({ ok: true });
  } catch (e) {
    res.status(400).json({ ok: false, error: e.message });
  }
});

app.post("/api/install/run", async (req, res) => {
  const cfg = req.body;
  if (!cfg || !cfg.database || !cfg.user) return res.status(400).json({ ok: false, error: "Missing fields" });
  try {
    // Override global DB config for this request
    global.DB_CONFIG = { host: cfg.host, port: cfg.port || 3306, user: cfg.user, password: cfg.password, database: cfg.database };
    // Force pool recreation
    const db = require("./api/db");
    // eslint-disable-next-line no-underscore-dangle
    if (db._pool) { await db._pool.end().catch(() => {}); db._pool = null; }
    const { createTables, ensureSeed } = require("./api/seed");
    await createTables();
    await ensureSeed();
    // Persist config
    fs.writeFileSync(configPath, JSON.stringify(global.DB_CONFIG, null, 2));
    res.json({ ok: true });
  } catch (e) {
    res.status(500).json({ ok: false, error: e.message });
  }
});

// API routes
app.use("/api", router);

// Serve static React frontend
const publicDir = path.join(__dirname, "public");
if (fs.existsSync(publicDir)) {
  app.use(express.static(publicDir));
  // SPA fallback — serve index.html for all non-API routes
  app.get("*", (req, res) => {
    const indexFile = path.join(publicDir, "index.html");
    if (fs.existsSync(indexFile)) {
      res.sendFile(indexFile);
    } else {
      res.status(404).send("Frontend not built. Please run the build script.");
    }
  });
}

const PORT = process.env.PORT || 3000;

ensureSeed()
  .then(() => {
    app.listen(PORT, () => {
      console.log(`ScholarExam running on port ${PORT}`);
    });
  })
  .catch((err) => {
    console.error("Seed failed:", err.message);
    // Start anyway
    app.listen(PORT, () => {
      console.log(`ScholarExam running on port ${PORT} (seed skipped)`);
    });
  });
