import type { Request, Response, NextFunction } from 'express';
import { hasDespachoFeature, type DespachoPlan } from '@horux/shared';
import { prisma } from '../config/database.js';

const planCache = new Map<string, { plan: string; expires: number }>();

/**
 * Middleware factory that gates routes based on tenant plan features.
 * Usage: requireFeature('reportes') — blocks access if tenant's plan lacks the feature.
 *
 * Tras eliminar Horux 360 legacy, todos los planes son del catálogo despacho.
 * Un plan desconocido (no en DESPACHO_PLANS) hace que `hasDespachoFeature`
 * retorne false → 403, lo cual es el comportamiento defensivo correcto.
 */
export function requireFeature(feature: string) {
  return async (req: Request, res: Response, next: NextFunction) => {
    if (!req.user) return res.status(401).json({ message: 'No autenticado' });

    let plan: string;
    const cached = planCache.get(req.user.tenantId);
    if (cached && cached.expires > Date.now()) {
      plan = cached.plan;
    } else {
      const tenant = await prisma.tenant.findUnique({
        where: { id: req.user.tenantId },
        select: { plan: true },
      });
      if (!tenant) return res.status(404).json({ message: 'Tenant no encontrado' });
      plan = tenant.plan;
      planCache.set(req.user.tenantId, { plan, expires: Date.now() + 5 * 60 * 1000 });
    }

    if (!hasDespachoFeature(plan as DespachoPlan, feature)) {
      return res.status(403).json({
        message: 'Tu plan no incluye esta función. Contacta soporte para upgrade.',
      });
    }

    next();
  };
}
