// AGENTFORGE-IA — Billing: Planes (cliente) + Facturación (admin)

function ScreenBilling({ initialTab = 'planes' }) {
  const normalizedInitialTab = initialTab === 'facturacion' ? 'facturacion' : 'planes';
  const [activeTab, setActiveTab] = React.useState(normalizedInitialTab);
  const routeLockedTab = initialTab === 'planes' || initialTab === 'facturacion';
  const [subData, setSubData] = React.useState(undefined); // undefined=loading, null=error
  const [isAdmin, setIsAdmin] = React.useState(false);
  const [adminData, setAdminData] = React.useState(null); // { stats, records }
  const [adminLoading, setAdminLoading] = React.useState(false);
  const [planUpdating, setPlanUpdating] = React.useState(''); // plan name being updated
  const [portalLoading, setPortalLoading] = React.useState(false);
  const [planError, setPlanError] = React.useState('');
  const [planSuccess, setPlanSuccess] = React.useState('');
  const [searchTerm, setSearchTerm] = React.useState('');
  const [statusFilter, setStatusFilter] = React.useState('');
  const [planFilter, setPlanFilter] = React.useState('');
  const [openMenu, setOpenMenu] = React.useState(null); // { customerId, top, left }
  const [patchLoading, setPatchLoading] = React.useState(''); // customer_id:action

  // ─── Helpers ────────────────────────────────────────────────────────────────

  const getToken = () => sessionStorage.getItem('af_token') || '';

  const authHeaders = () => ({
    'Authorization': 'Bearer ' + getToken(),
    'Content-Type': 'application/json',
  });

  /**
   * Formats a date string to "DD MMM YYYY".
   */
  const formatDate = (value) => {
    if (!value) return '—';
    try {
      return new Date(value).toLocaleDateString('es-ES', {
        day: '2-digit', month: 'short', year: 'numeric',
      });
    } catch (_) {
      return String(value);
    }
  };

  /**
   * Formats a date to "DD/MM/YY" for compact table cells.
   */
  const formatDateShort = (value) => {
    if (!value) return '—';
    try {
      return new Date(value).toLocaleDateString('es-ES', {
        day: '2-digit', month: '2-digit', year: '2-digit',
      });
    } catch (_) {
      return String(value);
    }
  };

  /**
   * Returns badge metadata for a subscription status string.
   */
  const getStatusMeta = (status) => {
    const map = {
      active:   { label: 'Activa',     color: 'var(--ok)',   bg: 'rgba(52,211,153,0.12)' },
      past_due: { label: 'Impago',     color: 'var(--bad)',  bg: 'rgba(248,113,113,0.12)' },
      canceled: { label: 'Cancelada',  color: 'var(--ink-3)', bg: 'var(--bg-3)' },
      trialing: { label: 'Prueba',     color: '#60a5fa',     bg: 'rgba(96,165,250,0.12)' },
    };
    return map[status] || { label: status || '—', color: 'var(--ink-3)', bg: 'var(--bg-3)' };
  };

  /**
   * Returns progress bar color based on token usage percentage.
   */
  const getBarColor = (pct) => {
    if (pct >= 100) return 'var(--bad)';
    if (pct >= 80)  return 'var(--warn)';
    return 'var(--ok)';
  };

  // ─── Data loading ────────────────────────────────────────────────────────────

  /**
   * Loads current user subscription and checks admin status.
   */
  const loadAdminData = async () => {
    setAdminLoading(true);
    const params = new URLSearchParams();
    if (statusFilter) params.set('status', statusFilter);
    if (planFilter)   params.set('plan', planFilter);
    if (searchTerm)   params.set('search', searchTerm);
    try {
      const res = await fetch('/api/v1/billing/admin/customers?' + params.toString(), {
        headers: { 'Authorization': 'Bearer ' + getToken() },
      });
      if (res.ok) {
        const rows = await res.json();
        const records = Array.isArray(rows) ? rows : [];
        const totalActive = records.filter((r) => r.status === 'active').length;
        const totalPastDue = records.filter((r) => r.status === 'past_due').length;
        const totalPaused = records.filter((r) => !!r.is_paused).length;
        const planPriceMap = { starter: 25, professional: 69, enterprise: 179 };
        const mrrEur = records.reduce((sum, r) => {
          if (r.status !== 'active') return sum;
          return sum + (planPriceMap[String(r.plan).toLowerCase()] || 0);
        }, 0);
        setAdminData({
          stats: {
            mrr_eur: mrrEur,
            total_active: totalActive,
            total_past_due: totalPastDue,
            total_paused: totalPaused,
            total_records: records.length,
          },
          records,
        });
      } else {
        window.afNotify && window.afNotify('Error al cargar datos de facturación');
      }
    } catch (_) {
      window.afNotify && window.afNotify('Error de red');
    } finally {
      setAdminLoading(false);
    }
  };

  // Mount: load subscription + check admin
  React.useEffect(() => {
    const token = sessionStorage.getItem('af_token') || '';
    const headers = { 'Authorization': 'Bearer ' + token };
    Promise.all([
      fetch('/api/v1/billing/my-subscription', { headers }).then(r => r.json()),
      fetch('/api/v1/customers/me', { headers }).then(r => r.json()),
    ]).then(([sub, me]) => {
      setSubData(sub);
      setIsAdmin(!!me.is_admin);
    }).catch(() => setSubData(null));
  }, []);

  // Admin tab: reload on tab change or filter change (debounced)
  React.useEffect(() => {
    if (activeTab !== 'facturacion' || !isAdmin) return;
    const timer = setTimeout(loadAdminData, 300);
    return () => clearTimeout(timer);
  }, [activeTab, isAdmin, searchTerm, statusFilter, planFilter]);

  React.useEffect(() => {
    setActiveTab(normalizedInitialTab);
  }, [normalizedInitialTab]);

  // Close dropdown on outside click
  React.useEffect(() => {
    if (!openMenu) return;
    const handler = () => setOpenMenu(null);
    const onResize = () => setOpenMenu(null);
    document.addEventListener('click', handler);
    window.addEventListener('resize', onResize);
    window.addEventListener('scroll', onResize, true);
    return () => {
      document.removeEventListener('click', handler);
      window.removeEventListener('resize', onResize);
      window.removeEventListener('scroll', onResize, true);
    };
  }, [openMenu]);

  // ─── Actions ─────────────────────────────────────────────────────────────────

  const handleChangePlan = async (planName) => {
    setPlanUpdating(planName);
    setPlanError('');
    setPlanSuccess('');
    const prev = subData;
    // Optimistic update to make the UX deterministic even with API latency.
    setSubData((current) => current ? { ...current, plan: planName } : current);
    try {
      const res = await fetch('/api/v1/billing/plan', {
        method: 'PUT',
        headers: authHeaders(),
        body: JSON.stringify({ plan: planName }),
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({}));
        const msg = err.detail || 'No se pudo actualizar el plan';
        setPlanError(msg);
        setSubData(prev);
        window.afNotify && window.afNotify(msg);
        try {
          // Re-sync suave por si hay estado intermedio en backend
          const fresh = await fetch('/api/v1/billing/my-subscription?_ts=' + Date.now(), {
            headers: { 'Authorization': 'Bearer ' + getToken() },
            cache: 'no-store',
          });
          if (fresh.ok) setSubData(await fresh.json());
        } catch (_) {}
        return;
      }
      const updated = await res.json();
      setSubData(updated);
      setPlanSuccess('Plan actualizado a ' + planName);
      window.afNotify && window.afNotify('Plan actualizado a ' + planName);
      try {
        // Hard re-sync after success to avoid stale state from intermediaries/proxies.
        const fresh = await fetch('/api/v1/billing/my-subscription?_ts=' + Date.now(), {
          headers: { 'Authorization': 'Bearer ' + getToken() },
          cache: 'no-store',
        });
        if (fresh.ok) setSubData(await fresh.json());
      } catch (_) {}
    } catch (_) {
      setSubData(prev);
      window.afNotify && window.afNotify('Error de red al actualizar plan');
    } finally {
      setPlanUpdating('');
    }
  };

  const handlePortal = async () => {
    setPortalLoading(true);
    try {
      const res = await fetch('/api/v1/billing/portal', {
        headers: { 'Authorization': 'Bearer ' + getToken() },
      });
      if (!res.ok) {
        window.afNotify && window.afNotify('Sin cuenta de facturación activa');
        return;
      }
      const payload = await res.json().catch(() => ({}));
      if (payload.portal_url) {
        window.open(payload.portal_url, '_blank');
      } else {
        window.afNotify && window.afNotify('Portal no disponible');
      }
    } catch (_) {
      window.afNotify && window.afNotify('Error de red al abrir portal');
    } finally {
      setPortalLoading(false);
    }
  };

  const handlePatch = async (customerId, action, successMsg) => {
    const key = customerId + ':' + action;
    setPatchLoading(key);
    try {
      const res = await fetch('/api/v1/billing/admin/customers/' + encodeURIComponent(customerId) + '/action', {
        method: 'POST',
        headers: authHeaders(),
        body: JSON.stringify({ action }),
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({}));
        window.afNotify && window.afNotify(err.detail || 'Error al aplicar cambio');
        return;
      }
      const updated = await res.json();
      setAdminData(prev => {
        if (!prev) return prev;
        const nextRecords = prev.records.map((r) =>
          r.customer_id === customerId ? { ...r, ...updated } : r
        );
        const totalActive = nextRecords.filter((r) => r.status === 'active').length;
        const totalPastDue = nextRecords.filter((r) => r.status === 'past_due').length;
        const totalPaused = nextRecords.filter((r) => !!r.is_paused).length;
        const planPriceMap = { starter: 25, professional: 69, enterprise: 179 };
        const mrrEur = nextRecords.reduce((sum, r) => {
          if (r.status !== 'active') return sum;
          return sum + (planPriceMap[String(r.plan).toLowerCase()] || 0);
        }, 0);
        return {
          ...prev,
          stats: {
            mrr_eur: mrrEur,
            total_active: totalActive,
            total_past_due: totalPastDue,
            total_paused: totalPaused,
            total_records: nextRecords.length,
          },
          records: nextRecords,
        };
      });
      window.afNotify && window.afNotify(successMsg || 'Cambio aplicado');
    } catch (_) {
      window.afNotify && window.afNotify('Error de red');
    } finally {
      setPatchLoading('');
      setOpenMenu(null);
    }
  };

  const exportCSV = () => {
    if (!adminData || !adminData.records) return;
    const BOM = '﻿';
    const headers = [
      'ID Cliente', 'Nombre', 'Email', 'Plan', 'Estado',
      'Tokens Permitidos', 'Tokens Usados', '% Consumo',
      'Stripe Customer ID', 'Stripe Suscripcion ID',
      'Fin Periodo', 'Pausada', 'Fecha Alta',
    ];
    const rows = adminData.records.map(r => [
      r.customer_id, r.customer_name, r.customer_email,
      r.plan, r.status, r.tokens_allowed, r.tokens_used_this_month,
      r.tokens_usage_pct + '%',
      r.stripe_customer_id, r.stripe_subscription_id,
      r.current_period_end ? new Date(r.current_period_end).toLocaleDateString('es-ES') : '',
      r.is_paused ? 'Si' : 'No',
      r.created_at ? new Date(r.created_at).toLocaleDateString('es-ES') : '',
    ]);
    const csv = BOM + [headers, ...rows]
      .map(r => r.map(v => `"${String(v == null ? '' : v).replace(/"/g, '""')}"`).join(','))
      .join('\n');
    const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `facturacion_${new Date().toISOString().slice(0, 10)}.csv`;
    a.click();
    URL.revokeObjectURL(url);
    window.afNotify && window.afNotify('CSV exportado');
  };

  const getLastActionLabel = (record) => {
    if (!record) return '—';
    const last = String(record.last_payment_status || '').toLowerCase();
    if (last === 'gift') return 'Obsequio';
    if (last === 'paid') return 'Cobro correcto';
    if (last === 'failed') return 'Cobro fallido';
    if (record.is_paused) return 'Pausada';
    if (record.status === 'active') return 'Activada';
    if (record.status === 'past_due') return 'Vencida';
    return '—';
  };

  // ─── Derived values ───────────────────────────────────────────────────────────

  const tokenAllowed = Number(subData?.tokens_allowed || 0);
  const tokenUsed    = Number(subData?.tokens_used_this_month || 0);
  const tokenPct     = tokenAllowed > 0 ? Math.min(100, Math.round((tokenUsed / tokenAllowed) * 100)) : 0;

  const currentPlan  = String(subData?.plan || '').toLowerCase();

  const PLANS = [
    {
      id: 'starter',
      label: 'Starter',
      price: '€25/mes',
      tokens: '500k tokens/mes',
      features: [
        '1 agente',
        'Soporte estandar',
        'Ejecuciones basicas',
        'Sin acceso API',
        'Analytics basico',
      ],
    },
    {
      id: 'professional',
      label: 'Professional',
      price: '€69/mes',
      tokens: '1.5M tokens/mes',
      popular: true,
      features: [
        'Hasta 5 agentes',
        'Soporte prioritario',
        'Ejecuciones avanzadas',
        'Acceso API',
        'Analytics completo',
      ],
    },
    {
      id: 'enterprise',
      label: 'Enterprise',
      price: '€179/mes',
      tokens: '5M tokens/mes',
      features: [
        'Agentes ilimitados',
        'Soporte dedicado',
        'Sin limite de ejecuciones',
        'Acceso API',
        'Analytics empresarial',
      ],
    },
  ];

  const PLAN_ORDER = { starter: 0, professional: 1, enterprise: 2 };

  const getPlanCTA = (planId) => {
    if (planId === currentPlan) return { text: 'Plan actual', variant: 'disabled' };
    const cur = PLAN_ORDER[currentPlan] ?? -1;
    const target = PLAN_ORDER[planId] ?? 0;
    if (target > cur) return { text: 'Mejorar a ' + PLANS.find(p => p.id === planId).label, variant: 'primary' };
    return { text: 'Cambiar a ' + PLANS.find(p => p.id === planId).label, variant: 'secondary' };
  };

  // ─── Sub-components ───────────────────────────────────────────────────────────

  const StatusBadge = ({ status, small }) => {
    const meta = getStatusMeta(status);
    return (
      <span style={{
        display: 'inline-flex', alignItems: 'center', gap: 5,
        padding: small ? '2px 7px' : '4px 10px',
        borderRadius: 999,
        background: meta.bg,
        color: meta.color,
        fontWeight: 700,
        fontSize: small ? 11 : 12,
        whiteSpace: 'nowrap',
      }}>
        <span style={{ width: 6, height: 6, borderRadius: '50%', background: meta.color, flexShrink: 0 }} />
        {meta.label}
      </span>
    );
  };

  const PlanBadge = ({ plan }) => {
    const styles = {
      starter:      { bg: 'var(--bg-3)',               color: 'var(--ink-2)' },
      professional: { bg: 'rgba(59,130,246,0.15)',      color: '#3b82f6' },
      enterprise:   { bg: 'rgba(139,92,246,0.15)',      color: '#8b5cf6' },
    };
    const s = styles[String(plan).toLowerCase()] || styles.starter;
    const labels = { starter: 'Starter', professional: 'Professional', enterprise: 'Enterprise' };
    return (
      <span style={{
        padding: '2px 8px', borderRadius: 'var(--r-sm)', fontSize: 11, fontWeight: 700,
        background: s.bg, color: s.color, whiteSpace: 'nowrap',
      }}>
        {labels[String(plan).toLowerCase()] || plan || '—'}
      </span>
    );
  };

  const MiniBar = ({ pct }) => (
    <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
      <div style={{ width: 80, height: 4, background: 'var(--bg-3)', borderRadius: 999, overflow: 'hidden', flexShrink: 0 }}>
        <div style={{ width: Math.min(100, pct) + '%', height: '100%', background: getBarColor(pct), transition: 'width 0.3s' }} />
      </div>
      <span style={{ fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--mono)' }}>{pct}%</span>
    </div>
  );

  const SkeletonRow = () => (
    <tr>
      {[...Array(8)].map((_, i) => (
        <td key={i} style={{ padding: '11px 14px' }}>
          <div style={{ height: 12, background: 'var(--bg-3)', borderRadius: 4, width: i === 0 ? 120 : 70, animation: 'pulse 1.5s infinite' }} />
        </td>
      ))}
    </tr>
  );

  // ─── Tab: Planes ──────────────────────────────────────────────────────────────

  const renderPlanes = () => {
    if (subData === undefined) {
      return (
        <div style={{ background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 'var(--r-md)', padding: 24, color: 'var(--ink-3)' }}>
          Cargando suscripcion...
        </div>
      );
    }
    if (subData === null) {
      return (
        <div style={{ background: 'var(--bg-2)', border: '1px solid var(--bad)', borderRadius: 'var(--r-md)', padding: 24, color: 'var(--bad)' }}>
          No se pudo cargar la suscripcion. Recarga la pagina.
        </div>
      );
    }

    return (
      <div style={{ display: 'grid', gap: 20 }}>

        {/* Subscription summary card */}
        <div style={{ background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 'var(--r-md)', padding: 24 }}>

          {subData.is_paused && (
            <div style={{
              background: 'rgba(245,158,11,0.12)', border: '1px solid var(--warn)',
              borderRadius: 'var(--r-sm)', padding: '10px 14px', marginBottom: 20,
              color: 'var(--warn)', fontWeight: 600, fontSize: 13,
            }}>
              Cuenta pausada por impago. Los agentes IA no pueden ejecutarse hasta que regularices el pago.
            </div>
          )}

          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(140px,1fr))', gap: 24 }}>

            {/* Plan actual */}
            <div>
              <div style={{ fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.07em', color: 'var(--ink-3)', fontFamily: 'var(--mono)', marginBottom: 6 }}>Plan actual</div>
              <div style={{ fontSize: 22, fontWeight: 700, textTransform: 'capitalize' }}>
                {subData.has_subscription ? (subData.plan || '—') : 'Sin plan'}
              </div>
            </div>

            {/* Estado */}
            <div>
              <div style={{ fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.07em', color: 'var(--ink-3)', fontFamily: 'var(--mono)', marginBottom: 6 }}>Estado</div>
              <StatusBadge status={subData.status} />
            </div>

            {/* Renovacion */}
            <div>
              <div style={{ fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.07em', color: 'var(--ink-3)', fontFamily: 'var(--mono)', marginBottom: 6 }}>Renovacion</div>
              <div style={{ fontSize: 15, fontWeight: 600 }}>{formatDate(subData.current_period_end)}</div>
            </div>

            {/* Tokens */}
            <div>
              <div style={{ fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.07em', color: 'var(--ink-3)', fontFamily: 'var(--mono)', marginBottom: 6 }}>Tokens este mes</div>
              <div style={{ fontSize: 18, fontWeight: 700 }}>
                {tokenUsed.toLocaleString('es-ES')}
                <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--ink-3)' }}> / {tokenAllowed.toLocaleString('es-ES')}</span>
              </div>
              <div style={{ height: 6, background: 'var(--bg-3)', borderRadius: 999, overflow: 'hidden', marginTop: 8 }}>
                <div style={{ width: tokenPct + '%', height: '100%', background: getBarColor(tokenPct), transition: 'width 0.3s' }} />
              </div>
              <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 4, fontFamily: 'var(--mono)' }}>
                {tokenUsed.toLocaleString('es-ES')} de {tokenAllowed.toLocaleString('es-ES')} ({tokenPct}%)
              </div>
            </div>

          </div>
        </div>

        {/* Plan cards */}
        {planError && (
          <div style={{ background: 'rgba(248,113,113,0.12)', border: '1px solid var(--bad)', color: 'var(--bad)', borderRadius: 'var(--r-sm)', padding: '10px 12px', fontSize: 13 }}>
            {planError}
          </div>
        )}
        {planSuccess && (
          <div style={{ background: 'rgba(52,211,153,0.12)', border: '1px solid var(--ok)', color: 'var(--ok)', borderRadius: 'var(--r-sm)', padding: '10px 12px', fontSize: 13 }}>
            {planSuccess}
          </div>
        )}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(240px,1fr))', gap: 16 }}>
          {PLANS.map(plan => {
            const isCurrent = plan.id === currentPlan;
            const cta = getPlanCTA(plan.id);
            const isUpdating = planUpdating === plan.id;
            return (
              <div key={plan.id} style={{
                background: 'var(--bg-2)',
                border: isCurrent ? '2px solid var(--brand)' : '1px solid var(--line)',
                borderRadius: 'var(--r-md)',
                padding: 24,
                display: 'flex', flexDirection: 'column', gap: 16,
                transform: isCurrent ? 'translateY(-2px)' : 'none',
                transition: 'transform 0.15s',
                position: 'relative',
              }}>

                {/* Badges */}
                <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', minHeight: 22 }}>
                  {isCurrent && (
                    <span style={{ padding: '2px 8px', borderRadius: 999, background: 'rgba(52,211,153,0.15)', color: 'var(--ok)', fontSize: 11, fontWeight: 700 }}>
                      Plan actual
                    </span>
                  )}
                  {plan.popular && (
                    <span style={{ padding: '2px 8px', borderRadius: 999, background: 'rgba(var(--brand-rgb, 99,102,241),0.12)', color: 'var(--brand)', fontSize: 11, fontWeight: 700 }}>
                      Mas popular
                    </span>
                  )}
                </div>

                {/* Name + price */}
                <div>
                  <div style={{ fontSize: 18, fontWeight: 700 }}>{plan.label}</div>
                  <div style={{ fontSize: 22, fontWeight: 800, marginTop: 4 }}>{plan.price}</div>
                  <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 2, fontFamily: 'var(--mono)' }}>{plan.tokens}</div>
                </div>

                {/* Features */}
                <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 8, flex: 1 }}>
                  {plan.features.map((f, i) => (
                    <li key={i} style={{ display: 'flex', gap: 8, fontSize: 13, color: 'var(--ink-1)', alignItems: 'flex-start' }}>
                      <span style={{ color: 'var(--ok)', fontWeight: 700, flexShrink: 0 }}>&#10003;</span>
                      {f}
                    </li>
                  ))}
                </ul>

                {/* CTA */}
                {cta.variant === 'disabled' ? (
                  <button className="btn" disabled style={{ opacity: 0.5, cursor: 'default' }}>Plan actual</button>
                ) : cta.variant === 'primary' ? (
                  <button
                    className="btn btn-primary"
                    disabled={isUpdating || !!planUpdating}
                    onClick={() => handleChangePlan(plan.id)}
                    style={{ justifyContent: 'center' }}
                  >
                    {isUpdating ? 'Actualizando...' : cta.text}
                  </button>
                ) : (
                  <button
                    className="btn"
                    disabled={isUpdating || !!planUpdating}
                    onClick={() => handleChangePlan(plan.id)}
                    style={{ justifyContent: 'center' }}
                  >
                    {isUpdating ? 'Actualizando...' : cta.text}
                  </button>
                )}
              </div>
            );
          })}
        </div>

        {/* Billing portal */}
        <div style={{ background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 'var(--r-md)', padding: 24, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 16, flexWrap: 'wrap' }}>
          <div>
            <div style={{ fontWeight: 600, marginBottom: 4 }}>Portal de facturacion</div>
            <div style={{ fontSize: 13, color: 'var(--ink-3)', maxWidth: 520 }}>
              Gestiona metodos de pago, descarga facturas y actualiza datos de facturacion en el portal de Stripe.
            </div>
          </div>
          <button className="btn" onClick={handlePortal} disabled={portalLoading} style={{ flexShrink: 0 }}>
            <Icon name="credit-card" size={14} />
            {portalLoading ? 'Abriendo...' : 'Gestionar portal de pago →'}
          </button>
        </div>

      </div>
    );
  };

  // ─── Tab: Facturacion (admin) ─────────────────────────────────────────────────

  const renderFacturacion = () => {
    const stats = adminData?.stats;
    const records = adminData?.records || [];

    return (
      <div style={{ display: 'grid', gap: 20 }}>

        {/* KPI cards */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(160px,1fr))', gap: 12 }}>
          <div style={{ background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 'var(--r-md)', padding: '20px 24px', display: 'flex', flexDirection: 'column', gap: 8 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
              <span style={{ fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.07em', color: 'var(--ink-3)', fontFamily: 'var(--mono)' }}>MRR</span>
              <Icon name="trending-up" size={14} style={{ color: 'var(--ink-3)' }} />
            </div>
            <div style={{ fontSize: 26, fontWeight: 800 }}>€{stats ? Number(stats.mrr_eur || 0).toFixed(0) : '—'}</div>
            <div style={{ fontSize: 12, color: 'var(--ink-3)' }}>Ingresos Recurrentes Mensuales</div>
          </div>

          <div style={{ background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 'var(--r-md)', padding: '20px 24px', display: 'flex', flexDirection: 'column', gap: 8 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
              <span style={{ fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.07em', color: 'var(--ok)', fontFamily: 'var(--mono)' }}>Activas</span>
              <Icon name="check-circle" size={14} style={{ color: 'var(--ok)' }} />
            </div>
            <div style={{ fontSize: 26, fontWeight: 800, color: 'var(--ok)' }}>{stats ? stats.total_active : '—'}</div>
            <div style={{ fontSize: 12, color: 'var(--ink-3)' }}>Suscripciones activas</div>
          </div>

          <div style={{ background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 'var(--r-md)', padding: '20px 24px', display: 'flex', flexDirection: 'column', gap: 8 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
              <span style={{ fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.07em', color: 'var(--warn)', fontFamily: 'var(--mono)' }}>En riesgo</span>
              <Icon name="alert-triangle" size={14} style={{ color: 'var(--warn)' }} />
            </div>
            <div style={{ fontSize: 26, fontWeight: 800, color: 'var(--warn)' }}>
              {stats ? (Number(stats.total_past_due || 0) + Number(stats.total_paused || 0)) : '—'}
            </div>
            <div style={{ fontSize: 12, color: 'var(--ink-3)' }}>En riesgo o pausadas</div>
          </div>

          <div style={{ background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 'var(--r-md)', padding: '20px 24px', display: 'flex', flexDirection: 'column', gap: 8 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
              <span style={{ fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.07em', color: 'var(--ink-3)', fontFamily: 'var(--mono)' }}>Total</span>
              <Icon name="users" size={14} style={{ color: 'var(--ink-3)' }} />
            </div>
            <div style={{ fontSize: 26, fontWeight: 800 }}>{stats ? stats.total_records : '—'}</div>
            <div style={{ fontSize: 12, color: 'var(--ink-3)' }}>Total registros</div>
          </div>
        </div>

        {/* Filters + export */}
        <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center' }}>
          <input
            className="input"
            placeholder="Buscar por nombre o email..."
            value={searchTerm}
            onChange={e => setSearchTerm(e.target.value)}
            style={{ minWidth: 220, flex: 1 }}
          />
          <select className="select" value={statusFilter} onChange={e => setStatusFilter(e.target.value)} style={{ width: 150 }}>
            <option value="">Estado: todos</option>
            <option value="active">Activa</option>
            <option value="past_due">Impago</option>
            <option value="canceled">Cancelada</option>
            <option value="trialing">Prueba</option>
          </select>
          <select className="select" value={planFilter} onChange={e => setPlanFilter(e.target.value)} style={{ width: 150 }}>
            <option value="">Plan: todos</option>
            <option value="starter">Starter</option>
            <option value="professional">Professional</option>
            <option value="enterprise">Enterprise</option>
          </select>
          <button className="btn" onClick={exportCSV} disabled={!adminData}>
            <Icon name="download" size={13} /> Exportar CSV
          </button>
          {adminData && (
            <span style={{ fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--mono)', marginLeft: 4 }}>
              {records.length} registros
            </span>
          )}
        </div>

        {/* Table */}
        <div style={{ background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 'var(--r-md)', overflow: 'visible' }}>
          <div style={{ overflowX: 'auto' }}>
            <table style={{ width: '100%', borderCollapse: 'collapse' }}>
              <thead>
                <tr>
                  {['Cliente', 'Email', 'Plan', 'Estado', 'Tokens', 'Renovacion', 'Pausada', 'Ultima accion', 'Acciones'].map(h => (
                    <th key={h} style={{
                      background: 'var(--bg-3)', padding: '10px 14px',
                      fontSize: 11, fontWeight: 700, textTransform: 'uppercase',
                      letterSpacing: '0.07em', color: 'var(--ink-3)',
                      fontFamily: 'var(--mono)', borderBottom: '1px solid var(--line)',
                      whiteSpace: 'nowrap', textAlign: 'left',
                    }}>{h}</th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {adminLoading && !adminData && (
                  [1, 2, 3, 4].map(i => <SkeletonRow key={i} />)
                )}
                {adminLoading && adminData && (
                  <tr>
                    <td colSpan={9} style={{ padding: '10px 14px', color: 'var(--ink-3)', fontSize: 12 }}>
                      Actualizando...
                    </td>
                  </tr>
                )}
                {!adminLoading && adminData && records.length === 0 && (
                  <tr>
                    <td colSpan={9} style={{ padding: '24px 14px', color: 'var(--ink-3)', textAlign: 'center' }}>
                      No hay registros con los filtros aplicados.
                    </td>
                  </tr>
                )}
                {records.map(r => {
                  const usagePct = Number(r.tokens_usage_pct || 0);
                  const isMenuOpen = openMenu && openMenu.customerId === r.customer_id;
                  return (
                    <tr
                      key={r.customer_id}
                      style={{ transition: 'background 0.1s' }}
                      onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-3)'}
                      onMouseLeave={e => e.currentTarget.style.background = ''}
                    >
                      {/* Cliente */}
                      <td style={{ padding: '11px 14px', fontSize: 13, color: 'var(--ink)', borderBottom: '1px solid var(--line)' }}>
                        <span style={{ fontWeight: 700 }}>{r.customer_name || '—'}</span>
                      </td>

                      {/* Email */}
                      <td style={{ padding: '11px 14px', fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--mono)', borderBottom: '1px solid var(--line)', whiteSpace: 'nowrap' }}>
                        {r.customer_email || '—'}
                      </td>

                      {/* Plan */}
                      <td style={{ padding: '11px 14px', borderBottom: '1px solid var(--line)' }}>
                        <PlanBadge plan={r.plan} />
                      </td>

                      {/* Estado */}
                      <td style={{ padding: '11px 14px', borderBottom: '1px solid var(--line)' }}>
                        <StatusBadge status={r.status} small />
                      </td>

                      {/* Tokens */}
                      <td style={{ padding: '11px 14px', borderBottom: '1px solid var(--line)' }}>
                        <MiniBar pct={usagePct} />
                      </td>

                      {/* Renovacion */}
                      <td style={{ padding: '11px 14px', fontSize: 12, color: 'var(--ink-2)', fontFamily: 'var(--mono)', borderBottom: '1px solid var(--line)', whiteSpace: 'nowrap' }}>
                        {formatDateShort(r.current_period_end)}
                      </td>

                      {/* Pausada */}
                      <td style={{ padding: '11px 14px', fontSize: 12, borderBottom: '1px solid var(--line)', whiteSpace: 'nowrap' }}>
                        {r.is_paused
                          ? <span style={{ color: 'var(--warn)', fontWeight: 600 }}>&#10003; Pausada</span>
                          : <span style={{ color: 'var(--ink-3)' }}>—</span>
                        }
                      </td>

                      {/* Ultima accion */}
                      <td style={{ padding: '11px 14px', fontSize: 12, color: 'var(--ink-2)', borderBottom: '1px solid var(--line)', whiteSpace: 'nowrap' }}>
                        {getLastActionLabel(r)}
                      </td>

                      {/* Acciones */}
                      <td style={{ padding: '11px 14px', borderBottom: '1px solid var(--line)', position: 'relative' }}>
                        <button
                          className="btn"
                          style={{ padding: '3px 10px', fontSize: 14, lineHeight: 1 }}
                          onClick={e => {
                            e.stopPropagation();
                            if (isMenuOpen) {
                              setOpenMenu(null);
                              return;
                            }
                            const rect = e.currentTarget.getBoundingClientRect();
                            const menuWidth = 220;
                            const menuHeight = 220;
                            const viewportW = window.innerWidth || 1280;
                            const viewportH = window.innerHeight || 800;
                            const showAbove = (viewportH - rect.bottom) < menuHeight && rect.top > menuHeight;
                            const left = Math.max(12, Math.min(rect.right - menuWidth, viewportW - menuWidth - 12));
                            const top = showAbove ? Math.max(12, rect.top - menuHeight - 6) : Math.min(viewportH - menuHeight - 12, rect.bottom + 6);
                            setOpenMenu({ customerId: r.customer_id, top, left });
                          }}
                        >
                          ···
                        </button>
                        {isMenuOpen && (
                          <div
                            style={{
                              position: 'fixed',
                              top: openMenu.top,
                              left: openMenu.left,
                              zIndex: 1200,
                              background: 'var(--bg-2)', border: '1px solid var(--line)',
                              borderRadius: 'var(--r-md)', padding: '6px 0',
                              minWidth: 220, maxHeight: 'min(280px, 60vh)',
                              overflowY: 'auto',
                              boxShadow: '0 12px 32px rgba(0,0,0,0.28)',
                            }}
                            onClick={e => e.stopPropagation()}
                          >
                            {/* Cambiar plan */}
                            <div style={{ padding: '6px 14px', fontSize: 11, color: 'var(--ink-3)', fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.07em', fontFamily: 'var(--mono)' }}>Estado</div>

                            <button
                              disabled={patchLoading.startsWith(r.customer_id)}
                              onClick={() => handlePatch(r.customer_id, r.is_paused ? 'resume' : 'pause', r.is_paused ? 'Suscripcion reanudada' : 'Suscripcion pausada')}
                              style={{
                                display: 'block', width: '100%', textAlign: 'left',
                                padding: '7px 14px', fontSize: 13, background: 'none', border: 'none',
                                cursor: 'pointer', color: r.is_paused ? 'var(--ok)' : 'var(--warn)',
                                opacity: patchLoading.startsWith(r.customer_id) ? 0.5 : 1,
                              }}
                              onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-3)'}
                              onMouseLeave={e => e.currentTarget.style.background = ''}
                            >
                              {r.is_paused ? 'Reanudar suscripcion' : 'Pausar suscripcion'}
                            </button>

                            <button
                              disabled={patchLoading.startsWith(r.customer_id)}
                              onClick={() => handlePatch(r.customer_id, 'payment_received', 'Suscripcion activada')}
                              style={{
                                display: 'block', width: '100%', textAlign: 'left',
                                padding: '7px 14px', fontSize: 13, background: 'none', border: 'none',
                                cursor: 'pointer', color: 'var(--ok)',
                                opacity: patchLoading.startsWith(r.customer_id) ? 0.5 : 1,
                              }}
                              onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-3)'}
                              onMouseLeave={e => e.currentTarget.style.background = ''}
                            >
                              Activar
                            </button>

                            <button
                              disabled={patchLoading.startsWith(r.customer_id)}
                              onClick={() => handlePatch(r.customer_id, 'payment_failed', 'Marcada como vencida')}
                              style={{
                                display: 'block', width: '100%', textAlign: 'left',
                                padding: '7px 14px', fontSize: 13, background: 'none', border: 'none',
                                cursor: 'pointer', color: 'var(--bad)',
                                opacity: patchLoading.startsWith(r.customer_id) ? 0.5 : 1,
                              }}
                              onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-3)'}
                              onMouseLeave={e => e.currentTarget.style.background = ''}
                            >
                              Marcar como vencida
                            </button>

                            <button
                              disabled={patchLoading.startsWith(r.customer_id)}
                              onClick={() => handlePatch(r.customer_id, 'gift', 'Obsequio aplicado')}
                              style={{
                                display: 'block', width: '100%', textAlign: 'left',
                                padding: '7px 14px', fontSize: 13, background: 'none', border: 'none',
                                cursor: 'pointer', color: '#f59e0b',
                                opacity: patchLoading.startsWith(r.customer_id) ? 0.5 : 1,
                              }}
                              onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-3)'}
                              onMouseLeave={e => e.currentTarget.style.background = ''}
                            >
                              Regalo / Obsequio
                            </button>
                          </div>
                        )}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>

      </div>
    );
  };

  // ─── Render ───────────────────────────────────────────────────────────────────

  return (
    <div>
      <div className="page-head">
        <h1>{activeTab === 'facturacion' ? 'Facturación' : 'Planes'}</h1>
        <span className="crumbs mono">
          administracion <span>›</span> <span style={{ color: 'var(--ink)' }}>{activeTab === 'facturacion' ? 'facturacion' : 'planes'}</span>
        </span>
      </div>

      <div className="section">

        {/* Tab bar */}
        {!routeLockedTab && <div style={{ display: 'flex', borderBottom: '1px solid var(--line)', marginBottom: 24, gap: 0 }}>
          {[
            { id: 'planes', label: 'Planes' },
            ...(isAdmin ? [{ id: 'facturacion', label: 'Facturacion' }] : []),
          ].map(tab => {
            const active = activeTab === tab.id;
            return (
              <button
                key={tab.id}
                onClick={() => setActiveTab(tab.id)}
                style={{
                  padding: '10px 20px', cursor: 'pointer', fontSize: 13, fontWeight: 600,
                  background: 'none', border: 'none', outline: 'none',
                  borderBottom: active ? '2px solid var(--brand)' : '2px solid transparent',
                  color: active ? 'var(--ink)' : 'var(--ink-3)',
                  marginBottom: -1, transition: 'color 0.15s, border-color 0.15s',
                }}
              >
                {tab.label}
              </button>
            );
          })}
        </div>}

        {/* Tab content */}
        {activeTab === 'planes' && renderPlanes()}
        {activeTab === 'facturacion' && isAdmin && renderFacturacion()}

      </div>
    </div>
  );
}

window.ScreenBilling = ScreenBilling;
