import React, { useState } from 'react'; import { Crown, Users, MapPin, Package, TrendingUp, RefreshCw, AlertCircle, CheckCircle, ArrowRight, Star, ExternalLink, Download } from 'lucide-react'; import { Button, Card, Badge, Modal } from '../../../../components/ui'; import { PageHeader } from '../../../../components/layout'; import { useAuthUser } from '../../../../stores/auth.store'; import { useCurrentTenant } from '../../../../stores'; import { useToast } from '../../../../hooks/ui/useToast'; import { subscriptionService, type UsageSummary, type AvailablePlans } from '../../../../api'; const SubscriptionPage: React.FC = () => { const user = useAuthUser(); const currentTenant = useCurrentTenant(); const { addToast } = useToast(); const [usageSummary, setUsageSummary] = useState(null); const [availablePlans, setAvailablePlans] = useState(null); const [subscriptionLoading, setSubscriptionLoading] = useState(false); const [upgradeDialogOpen, setUpgradeDialogOpen] = useState(false); const [selectedPlan, setSelectedPlan] = useState(''); const [upgrading, setUpgrading] = useState(false); // Load subscription data on component mount React.useEffect(() => { loadSubscriptionData(); }, []); const loadSubscriptionData = async () => { const tenantId = currentTenant?.id || user?.tenant_id; if (!tenantId) { addToast('No se encontró información del tenant', { type: 'error' }); return; } try { setSubscriptionLoading(true); const [usage, plans] = await Promise.all([ subscriptionService.getUsageSummary(tenantId), subscriptionService.getAvailablePlans() ]); setUsageSummary(usage); setAvailablePlans(plans); } catch (error) { console.error('Error loading subscription data:', error); addToast("No se pudo cargar la información de suscripción", { type: 'error' }); } finally { setSubscriptionLoading(false); } }; const handleUpgradeClick = (planKey: string) => { setSelectedPlan(planKey); setUpgradeDialogOpen(true); }; const handleUpgradeConfirm = async () => { const tenantId = currentTenant?.id || user?.tenant_id; if (!tenantId || !selectedPlan) { addToast('Información de tenant no disponible', { type: 'error' }); return; } try { setUpgrading(true); const validation = await subscriptionService.validatePlanUpgrade( tenantId, selectedPlan ); if (!validation.can_upgrade) { addToast(validation.reason || 'No se puede actualizar el plan', { type: 'error' }); return; } const result = await subscriptionService.upgradePlan(tenantId, selectedPlan); if (result.success) { addToast(result.message, { type: 'success' }); await loadSubscriptionData(); setUpgradeDialogOpen(false); setSelectedPlan(''); } else { addToast('Error al cambiar el plan', { type: 'error' }); } } catch (error) { console.error('Error upgrading plan:', error); addToast('Error al procesar el cambio de plan', { type: 'error' }); } finally { setUpgrading(false); } }; const ProgressBar: React.FC<{ value: number; className?: string }> = ({ value, className = '' }) => { const getProgressColor = () => { if (value >= 90) return 'bg-red-500'; if (value >= 80) return 'bg-yellow-500'; return 'bg-green-500'; }; return (
); }; return (
{subscriptionLoading ? (

Cargando información de suscripción...

) : !usageSummary || !availablePlans ? (

No se pudo cargar la información

Hubo un problema al cargar los datos de suscripción

) : ( <> {/* Current Plan Overview */}

Plan Actual: {subscriptionService.getPlanDisplayInfo(usageSummary.plan).name}

{usageSummary.status === 'active' ? 'Activo' : usageSummary.status}
Precio Mensual {subscriptionService.formatPrice(usageSummary.monthly_price)}
Próxima Facturación {new Date(usageSummary.next_billing_date).toLocaleDateString('es-ES', { day: '2-digit', month: '2-digit' })}
Usuarios {usageSummary.usage.users.current}/{usageSummary.usage.users.unlimited ? '∞' : usageSummary.usage.users.limit}
Ubicaciones {usageSummary.usage.locations.current}/{usageSummary.usage.locations.unlimited ? '∞' : usageSummary.usage.locations.limit}
{/* Usage Details */}

Uso de Recursos

{/* Users */}
Usuarios
{usageSummary.usage.users.current}/ {usageSummary.usage.users.unlimited ? '∞' : usageSummary.usage.users.limit}

{usageSummary.usage.users.usage_percentage}% utilizado {usageSummary.usage.users.unlimited ? 'Ilimitado' : `${usageSummary.usage.users.limit - usageSummary.usage.users.current} restantes`}

{/* Locations */}
Ubicaciones
{usageSummary.usage.locations.current}/ {usageSummary.usage.locations.unlimited ? '∞' : usageSummary.usage.locations.limit}

{usageSummary.usage.locations.usage_percentage}% utilizado {usageSummary.usage.locations.unlimited ? 'Ilimitado' : `${usageSummary.usage.locations.limit - usageSummary.usage.locations.current} restantes`}

{/* Products */}
Productos
{usageSummary.usage.products.current}/ {usageSummary.usage.products.unlimited ? '∞' : usageSummary.usage.products.limit}

{usageSummary.usage.products.usage_percentage}% utilizado {usageSummary.usage.products.unlimited ? 'Ilimitado' : 'Ilimitado'}

{/* Available Plans */}

Planes Disponibles

{Object.entries(availablePlans.plans).map(([planKey, plan]) => { const isCurrentPlan = usageSummary.plan === planKey; const getPlanColor = () => { switch (planKey) { case 'starter': return 'border-blue-500/30 bg-blue-500/5'; case 'professional': return 'border-purple-500/30 bg-purple-500/5'; case 'enterprise': return 'border-amber-500/30 bg-amber-500/5'; default: return 'border-[var(--border-primary)] bg-[var(--bg-secondary)]'; } }; return ( {plan.popular && (
Más Popular
)}

{plan.name}

{subscriptionService.formatPrice(plan.monthly_price)} /mes

{plan.description}

{plan.max_users === -1 ? 'Usuarios ilimitados' : `${plan.max_users} usuarios`}
{plan.max_locations === -1 ? 'Ubicaciones ilimitadas' : `${plan.max_locations} ubicación${plan.max_locations > 1 ? 'es' : ''}`}
{plan.max_products === -1 ? 'Productos ilimitados' : `${plan.max_products} productos`}
{/* Features Section */}
Funcionalidades Incluidas
{(() => { const getPlanFeatures = (planKey: string) => { switch (planKey) { case 'starter': return [ '✓ Panel de Control Básico', '✓ Gestión de Inventario', '✓ Gestión de Pedidos', '✓ Gestión de Proveedores', '✓ Punto de Venta Básico', '✗ Analytics Avanzados', '✗ Pronósticos IA', '✗ Insights Predictivos' ]; case 'professional': return [ '✓ Panel de Control Avanzado', '✓ Gestión de Inventario Completa', '✓ Analytics de Ventas', '✓ Pronósticos con IA (92% precisión)', '✓ Análisis de Rendimiento', '✓ Optimización de Producción', '✓ Integración POS', '✗ Insights Predictivos Avanzados' ]; case 'enterprise': return [ '✓ Todas las funcionalidades Professional', '✓ Insights Predictivos con IA', '✓ Analytics Multi-ubicación', '✓ Integración ERP', '✓ API Personalizada', '✓ Gestor de Cuenta Dedicado', '✓ Soporte 24/7 Prioritario', '✓ Demo Personalizada' ]; default: return []; } }; return getPlanFeatures(planKey).map((feature, index) => (
{feature}
)); })()}
{isCurrentPlan ? ( Plan Actual ) : ( )}
); })}
)} {/* Upgrade Modal */} {upgradeDialogOpen && selectedPlan && availablePlans && ( setUpgradeDialogOpen(false)} title="Confirmar Cambio de Plan" >

¿Estás seguro de que quieres cambiar tu plan de suscripción?

{availablePlans.plans[selectedPlan] && usageSummary && (
Plan actual: {subscriptionService.getPlanDisplayInfo(usageSummary.plan).name}
Nuevo plan: {availablePlans.plans[selectedPlan].name}
Nuevo precio: {subscriptionService.formatPrice(availablePlans.plans[selectedPlan].monthly_price)}/mes
)}
)}
); }; export default SubscriptionPage;