import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
import { UserRole } from '@prisma/client';
import { env } from '../config/env';
import { AppError } from './error-handler';

interface TokenPayload {
  id: string;
  email: string;
  role: UserRole;
  roles?: UserRole[];
}

export function authenticate(req: Request, _res: Response, next: NextFunction) {
  const header = req.headers.authorization;
  if (!header?.startsWith('Bearer ')) {
    throw new AppError(401, 'Authentication required', 'AUTH_REQUIRED');
  }

  const token = header.slice(7);

  try {
    const payload = jwt.verify(token, env.JWT_ACCESS_SECRET, { algorithms: ['HS256'] }) as TokenPayload;
    req.user = {
      id: payload.id,
      email: payload.email,
      role: payload.role,
      roles: payload.roles || [payload.role], // Backwards compat: old JWTs without roles
    };
    next();
  } catch {
    throw new AppError(401, 'Invalid or expired token', 'INVALID_TOKEN');
  }
}

export function optionalAuth(req: Request, _res: Response, next: NextFunction) {
  const header = req.headers.authorization;
  if (!header?.startsWith('Bearer ')) {
    next();
    return;
  }

  const token = header.slice(7);

  try {
    const payload = jwt.verify(token, env.JWT_ACCESS_SECRET, { algorithms: ['HS256'] }) as TokenPayload;
    req.user = {
      id: payload.id,
      email: payload.email,
      role: payload.role,
      roles: payload.roles || [payload.role],
    };
  } catch {
    // Token invalid — continue without user
  }

  next();
}
