// server.js
// Entry point for cPanel Node.js App (Passenger) — set the "Application
// startup file" to server.js and Node version to 22+.
// Run locally with:  node --experimental-sqlite server.js

require('dotenv').config();
const path = require('path');
const express = require('express');
const session = require('express-session');

const db = require('./src/db'); // also runs migrations + seed on first import

const contactRoutes = require('./src/routes/contact');
const newsletterRoutes = require('./src/routes/newsletter');
const contentRoutes = require('./src/routes/content');
const chatRoutes = require('./src/routes/chat');
const adminRoutes = require('./src/routes/admin');
const analyticsRoutes = require('./src/routes/analytics');
const invoicesRoutes = require('./src/routes/invoices');

const app = express();
const PORT = process.env.PORT || 3000;
const isProd = process.env.NODE_ENV === 'production';

app.set('trust proxy', 1); // cPanel usually sits behind a reverse proxy
app.disable('x-powered-by'); // don't advertise the framework to would-be attackers

// Raised from 200kb to 6mb so the Media admin page can accept base64 image
// uploads without needing an extra dependency like multer. Still bounded,
// and every admin write route sits behind requireAdmin + rate limiting.
app.use(express.json({ limit: '6mb' }));
app.use(express.urlencoded({ extended: true, limit: '6mb' }));

// ---- baseline security headers (kept dependency-free, no helmet) ----
app.use((req, res, next) => {
  res.set('X-Content-Type-Options', 'nosniff');
  res.set('X-Frame-Options', 'DENY');
  res.set('Referrer-Policy', 'strict-origin-when-cross-origin');
  res.set('Permissions-Policy', 'geolocation=(), camera=(), microphone=()');
  if (req.path.startsWith('/admin')) res.set('Cache-Control', 'no-store'); // never cache admin pages/data
  if (isProd) res.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
  next();
});

app.use(session({
  name: 'yst.sid',
  secret: process.env.SESSION_SECRET || 'change-this-secret-in-.env',
  resave: false,
  saveUninitialized: false,
  cookie: {
    httpOnly: true,
    sameSite: 'lax',
    secure: isProd, // requires HTTPS in production
    maxAge: 1000 * 60 * 60 * 8 // 8 hours
  }
}));

// ---- API routes ----
app.use('/api/contact', contactRoutes);
app.use('/api/newsletter', newsletterRoutes);
app.use('/api/chat', chatRoutes);
app.use('/api', contentRoutes); // exposes /api/stories, /api/insights, /api/press, /api/events, /api/media, /api/admin/*
app.use('/api/admin', adminRoutes);
app.use('/api/admin', invoicesRoutes); // exposes /api/admin/invoices/*, /api/admin/bank-accounts/*
app.use('/api', analyticsRoutes); // exposes /api/analytics/pageview, /api/admin/analytics/summary

app.get('/api/health', (req, res) => res.json({ ok: true, time: new Date().toISOString() }));

// ---- static sites ----
// Public marketing site
app.use(express.static(path.join(__dirname, '..', 'public'), { extensions: ['html'] }));
// Admin dashboard (protected client-side via /api/admin/me; keep it unlisted/unlinked from public nav)
app.use('/admin', express.static(path.join(__dirname, '..', 'admin'), { extensions: ['html'] }));

// Friendly 404 for unknown API routes
app.use('/api', (req, res) => res.status(404).json({ error: 'Not found' }));

// Friendly branded 404 page for any other unmatched route
app.use((req, res) => {
  res.status(404).sendFile(path.join(__dirname, '..', 'public', '404.html'));
});

app.listen(PORT, () => {
  const base = `http://localhost:${PORT}`;
  console.log('\n──────────────────────────────────────────────────');
  console.log('  Yellow Stone Traders & General Supplies — server is running');
  console.log('──────────────────────────────────────────────────');
  console.log(`  Public website : ${base}/index.html`);
  console.log(`  Admin login    : ${base}/admin/login.html`);
  console.log('──────────────────────────────────────────────────\n');
});
