/**
 * Authentication plugin for Fastify
 */

import type { FastifyPluginAsync, FastifyRequest, FastifyReply } from 'fastify';
import fp from 'fastify-plugin';
import jwt from '@fastify/jwt';
import type { AuthUser } from '@tracearr/shared';

declare module '@fastify/jwt' {
  interface FastifyJWT {
    payload: AuthUser;
    user: AuthUser;
  }
}

declare module 'fastify' {
  interface FastifyInstance {
    authenticate: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
    requireOwner: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
    requireMobile: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
  }
}

const authPlugin: FastifyPluginAsync = async (app) => {
  const secret = process.env.JWT_SECRET;

  if (!secret) {
    throw new Error('JWT_SECRET environment variable is required');
  }

  await app.register(jwt, {
    secret,
    sign: {
      algorithm: 'HS256',
    },
    cookie: {
      cookieName: 'token',
      signed: false,
    },
  });

  // Authenticate decorator - verifies JWT
  app.decorate('authenticate', async function (request: FastifyRequest, reply: FastifyReply) {
    try {
      await request.jwtVerify();
    } catch {
      reply.unauthorized('Invalid or expired token');
    }
  });

  // Require owner role decorator
  app.decorate('requireOwner', async function (request: FastifyRequest, reply: FastifyReply) {
    try {
      await request.jwtVerify();

      if (request.user.role !== 'owner') {
        reply.forbidden('Owner access required');
      }
    } catch {
      reply.unauthorized('Invalid or expired token');
    }
  });

  // Require mobile token decorator - validates token was issued for mobile app
  app.decorate('requireMobile', async function (request: FastifyRequest, reply: FastifyReply) {
    try {
      await request.jwtVerify();

      if (!request.user.mobile) {
        reply.forbidden('Mobile access token required');
      }
    } catch {
      reply.unauthorized('Invalid or expired token');
    }
  });
};

export default fp(authPlugin, {
  name: 'auth',
  dependencies: ['@fastify/cookie'],
});
