import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
import { config } from './config.js';
import { migrate, seed } from './db.js';
import { requestLogger } from './middleware/requestLogger.js';
import { apiRoutes } from './routes/index.js';
import { logger } from './services/logger.js';
import { effectiveTrustedOrigins } from './models/settingsModel.js';
import { startCatalogWorker } from './services/catalogWorker.js';
import { startPromotionWorker } from './services/promotionWorker.js';

// Fail fast in production rather than ship with well-known default secrets.
// These defaults are fine for local development but are publicly known, so a
// production deployment that kept them would have forgeable sessions and
// recoverable credential ciphertext.
function assertProductionSecrets() {
  if (!config.isProduction) return;
  const insecure = [];
  if (!process.env.JWT_SECRET || config.jwtSecret === 'dev-only-change-me') insecure.push('JWT_SECRET');
  if (!process.env.CREDENTIAL_STORE_KEY || config.credentialStoreKey === 'dev-only-credential-key') {
    insecure.push('CREDENTIAL_STORE_KEY');
  }
  if (config.defaultAdminPassword === 'change-me-now') insecure.push('DEFAULT_ADMIN_PASSWORD');
  if (insecure.length) {
    logger.error('Refusing to start in production with insecure default secrets', { insecure });
    throw new Error(`Set non-default values for: ${insecure.join(', ')} before starting in production.`);
  }
}

assertProductionSecrets();

migrate();
seed();

const app = express();

// The API always runs behind the Vite proxy (and typically a reverse proxy in
// production), so honor X-Forwarded-* to get the real client IP for rate
// limiting and logging.
app.set('trust proxy', true);

app.use(helmet({ contentSecurityPolicy: false }));
app.use(cors({
  origin(origin, callback) {
    // Read the effective allow-list per request so admin edits to
    // `trusted_origins` in the Config screen take effect without a restart.
    if (!origin || effectiveTrustedOrigins().includes(origin)) return callback(null, true);
    return callback(new Error(`Origin ${origin} is not allowed by CORS`));
  },
  credentials: true
}));
app.use(express.json({ limit: config.jsonLimit }));
app.use(requestLogger);
app.use('/api', apiRoutes);

app.use((error, req, res, next) => {
  logger.error('unhandled error', { error });
  res.status(500).json({ error: 'Unexpected server error' });
});

app.listen(config.port, () => {
  logger.info(`POSHManager API listening on ${config.port}`);
  startCatalogWorker();
  startPromotionWorker();
});
