import { FastifyRequest, FastifyReply } from 'fastify';
import jwt from 'jsonwebtoken';
import { env } from '../../config/env.js';
import { prisma } from '../../config/database.js';
import { errorResponse } from '../../utils/helpers.js';

export interface JwtPayload {
  tenantId: string;
  email: string;
}

declare module 'fastify' {
  interface FastifyRequest {
    tenantId?: string;
    tenant?: {
      id: string;
      name: string;
      email: string;
      slug: string;
      plan: string;
      isActive: boolean;
    };
  }
}

export async function authMiddleware(request: FastifyRequest, reply: FastifyReply) {
  const authHeader = request.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return errorResponse(reply, 'Authorization token required', 401);
  }

  const token = authHeader.slice(7);

  try {
    const decoded = jwt.verify(token, env.jwt.secret) as JwtPayload;

    const tenant = await prisma.tenant.findUnique({
      where: { id: decoded.tenantId },
      select: { id: true, name: true, email: true, slug: true, plan: true, isActive: true },
    });

    if (!tenant || !tenant.isActive) {
      return errorResponse(reply, 'Account not found or deactivated', 401);
    }

    request.tenantId = tenant.id;
    request.tenant = tenant;
  } catch {
    return errorResponse(reply, 'Invalid or expired token', 401);
  }
}

export function generateTokens(payload: JwtPayload) {
  const accessToken = jwt.sign(payload, env.jwt.secret, {
    expiresIn: env.jwt.expiresIn as string | number,
  } as jwt.SignOptions);

  const refreshToken = jwt.sign(
    { ...payload, type: 'refresh' },
    env.jwt.secret,
    { expiresIn: env.jwt.refreshExpiresIn as string | number } as jwt.SignOptions,
  );

  return { accessToken, refreshToken };
}
