<?php
// Prevent direct access
if (count(get_included_files()) === 1) {
    http_response_code(403);
    exit('Forbidden');
}

/**
 * PlanGuard — helpers reutilizables de gating por plan.
 *
 * Uso:
 *   $tenant = PlanGuard::load($db, $tenantId);
 *   if (!PlanGuard::permite($tenant, 'whatsapp'))    { ... }
 *   if (!PlanGuard::dentroDelLimite($tenant, 'convos')) { ... }
 *   if (!PlanGuard::puedeAgregarStaff($db, $tenant)) { ... }
 */
class PlanGuard {

    private static ?array $limits = null;

    private static function limits(): array {
        if (self::$limits === null) {
            self::$limits = require dirname(__DIR__, 2) . '/config/plan_limits.php';
        }
        return self::$limits;
    }

    /** Carga el tenant con sus columnas de billing desde la DB. */
    public static function load(PDO $db, int $tenantId): array {
        $stmt = $db->prepare(
            "SELECT id, plan, billing_status, convos_used_month,
                    current_period_end, mrr, setup_paid, seller_id
             FROM tenants WHERE id = :id AND deleted_at IS NULL LIMIT 1"
        );
        $stmt->execute([':id' => $tenantId]);
        $tenant = $stmt->fetch();
        if (!$tenant) {
            throw new RuntimeException("Tenant $tenantId not found");
        }
        return $tenant;
    }

    /**
     * ¿El plan del tenant permite este feature?
     * Features: 'whatsapp', 'recordatorios', 'badge', 'multi_sucursal'
     */
    public static function permite(array $tenant, string $feature): bool {
        $plan  = $tenant['plan'] ?? 'free';
        $limits = self::limits();
        $cfg   = $limits[$plan] ?? $limits['free'];
        return (bool) ($cfg[$feature] ?? false);
    }

    /**
     * ¿El tenant está dentro del límite para el recurso dado?
     * Recursos: 'convos'
     * Retorna true si puede seguir, false si alcanzó el tope.
     */
    public static function dentroDelLimite(array $tenant, string $recurso): bool {
        $plan   = $tenant['plan'] ?? 'free';
        $limits = self::limits();
        $cfg    = $limits[$plan] ?? $limits['free'];

        if ($recurso === 'convos') {
            $max = $cfg['convos_max'];
            if ($max === null) return true; // ilimitado
            return (int)($tenant['convos_used_month'] ?? 0) < $max;
        }

        return true;
    }

    /**
     * ¿El tenant puede agregar más staff?
     * Compara staff activos en DB contra staff_max del plan.
     */
    public static function puedeAgregarStaff(PDO $db, array $tenant): bool {
        $plan   = $tenant['plan'] ?? 'free';
        $limits = self::limits();
        $cfg    = $limits[$plan] ?? $limits['free'];
        $max    = $cfg['staff_max'];
        if ($max === null) return true;

        $stmt = $db->prepare(
            "SELECT COUNT(*) FROM staff WHERE tenant_id = :tid AND activo = 1"
        );
        $stmt->execute([':tid' => $tenant['id']]);
        return (int)$stmt->fetchColumn() < $max;
    }

    /**
     * ¿El tenant tiene una suscripción activa?
     * Considera active/trial con current_period_end en el futuro.
     */
    public static function estaActivo(array $tenant): bool {
        $status = $tenant['billing_status'] ?? 'free';
        if (in_array($status, ['active', 'free'], true)) return true;
        if ($status === 'trial') {
            $end = $tenant['current_period_end'] ?? null;
            return $end && strtotime($end) >= strtotime('today');
        }
        return false;
    }

    /** Devuelve la config completa del plan del tenant. */
    public static function config(array $tenant): array {
        $plan = $tenant['plan'] ?? 'free';
        $all  = self::limits();
        return $all[$plan] ?? $all['free'];
    }

    /**
     * Incrementa convos_used_month en 1 para el tenant.
     * Llamar desde AgentService después de cada respuesta enviada al cliente final.
     */
    public static function incrementarConvos(PDO $db, int $tenantId): void {
        $db->prepare(
            "UPDATE tenants SET convos_used_month = convos_used_month + 1 WHERE id = :id"
        )->execute([':id' => $tenantId]);
    }

    /**
     * Resetea convos_used_month para todos los tenants.
     * Ejecutar vía cron el 1ro de cada mes.
     */
    public static function resetearConvosMensuales(PDO $db): int {
        $stmt = $db->prepare("UPDATE tenants SET convos_used_month = 0 WHERE deleted_at IS NULL");
        $stmt->execute();
        return $stmt->rowCount();
    }

    /**
     * Retorna el mensaje de upgrade apropiado para el contexto.
     * El dashboard lo muestra cuando el tenant alcanza un tope.
     */
    public static function mensajeUpgrade(array $tenant, string $motivo): string {
        $plan = $tenant['plan'] ?? 'free';
        $msgs = [
            'convos'      => 'Llegaste al límite de conversaciones del plan gratuito. Mejorá tu plan para seguir atendiendo sin interrupciones.',
            'whatsapp'    => 'WhatsApp está disponible desde el plan Premium. Mejorá para conectar tu número.',
            'staff'       => 'Alcanzaste el máximo de staff para tu plan. Mejorá para agregar más colaboradores.',
            'multi_sucursal' => 'Las múltiples sucursales están disponibles en el plan Custom. Contactá a tu asesor.',
        ];
        return $msgs[$motivo] ?? 'Mejorá tu plan para acceder a esta función.';
    }
}
