import 'dotenv/config';
import express from 'express';
import cors from 'cors';
import pg from 'pg';
import { fileURLToPath } from 'node:url';

const { Pool } = pg;
import { dirname, resolve as resolvePath } from 'node:path';
import { config as loadEnv } from 'dotenv';

import { corsOptions } from '../shared/cors/policy.js';
import { requestLog } from '../shared/logging/request-log.js';
import { logger } from '../shared/logging/logger.js';
import { errorHandler } from '../shared/errors/handler.js';
import { loginLimiter, verifyLimiter } from '../shared/rate-limit/login.js';
import { extractBearerToken, verifyToken, TokenError } from '../shared/auth/verify.js';

import { createAuthRoutes } from './routes.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// auth/ lives at inventory-server/auth/, so .env one level up
loadEnv({ path: resolvePath(__dirname, '../.env') });

if (!process.env.JWT_SECRET) {
  logger.error('JWT_SECRET is not set; refusing to start');
  process.exit(1);
}

logger.info({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  database: process.env.DB_NAME,
  port: process.env.DB_PORT,
  auth_port: process.env.AUTH_PORT,
}, 'starting auth server');

const app = express();
const port = Number(process.env.AUTH_PORT) || 3011;

const pool = new Pool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  port: Number(process.env.DB_PORT) || 5432,
});

app.use(requestLog());
app.use(express.json({ limit: '1mb' }));
app.use(cors(corsOptions));

// Caddy forward_auth target: JWT signature check only, no DB hit.
// Returns 200 with X-User-Id / X-User-Username on success; 401 otherwise.
// Per-service middleware re-verifies independently; these headers are informational.
app.all('/verify', verifyLimiter, (req, res) => {
  try {
    const token = extractBearerToken(req.headers.authorization);
    const decoded = verifyToken(token, process.env.JWT_SECRET);
    res.set('X-User-Id', String(decoded.userId));
    if (decoded.username) res.set('X-User-Username', decoded.username);
    res.status(200).end();
  } catch (err) {
    if (err instanceof TokenError) {
      return res.status(401).json({ error: err.message });
    }
    res.status(401).json({ error: 'Invalid token' });
  }
});

// Login route gets its own rate limiter to slow credential stuffing.
app.use('/login', loginLimiter);

// Mount user-management + /login + /me from routes.js
app.use('/', createAuthRoutes({ pool }));

app.get('/health', (req, res) => res.json({ status: 'healthy' }));

app.use(errorHandler);

app.listen(port, () => {
  logger.info({ port }, 'auth server listening');
});
