import type { FastifyRequest, FastifyReply } from 'fastify';
import jwt from 'jsonwebtoken';
import type { User } from '@wa-ticketing/shared';

const JWT_SECRET = process.env.JWT_SECRET!;

export interface JwtPayload {
  sub: string;   // user id
  email: string;
  role: User['role'];
  /** Present for company_user; omitted on legacy JWTs until re-login */
  company_id?: string | null;
}

export async function authenticate(req: FastifyRequest, reply: FastifyReply) {
  const authHeader = req.headers.authorization;
  const token = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null;

  if (!token) {
    return reply.status(401).send({ error: 'Unauthorized' });
  }

  try {
    const payload = jwt.verify(token, JWT_SECRET) as JwtPayload;
    req.user = { ...payload, company_id: payload.company_id ?? null };
  } catch {
    return reply.status(401).send({ error: 'Invalid or expired token' });
  }
}

export function requireRole(...roles: User['role'][]) {
  return async (req: FastifyRequest, reply: FastifyReply) => {
    if (!req.user) {
      return reply.status(401).send({ error: 'Unauthorized' });
    }
    if (!roles.includes(req.user.role)) {
      return reply.status(403).send({ error: 'Forbidden' });
    }
  };
}

/** Blocks company portal users from staff-only routes (admin and agents only). */
export async function requireStaff(req: FastifyRequest, reply: FastifyReply) {
  if (!req.user) return reply.status(401).send({ error: 'Unauthorized' });
  if (req.user.role === 'company_user') return reply.status(403).send({ error: 'Forbidden' });
}

// Augment Fastify's request type
declare module 'fastify' {
  interface FastifyRequest {
    user?: JwtPayload;
  }
  interface FastifyInstance {
    io: import('socket.io').Server;
  }
}
