'use client'; import { useState, useEffect } from 'react'; import { Check, Crown, Zap, Building2, Rocket, AlertTriangle, ShieldAlert, CreditCard, QrCode, FileText, CheckCircle2, ShieldCheck } from 'lucide-react'; const staticPlans = [ { name: 'Starter', price: 49.90, icon: Zap, color: '#3b82f6', features: ['1 profissional', '10 serviços', '200 agendamentos/mês', 'Agendamento online', 'Página de reservas', 'Lembretes por e-mail', 'Relatórios básicos'] }, { name: 'Professional', price: 99.90, icon: Crown, color: '#6C63FF', featured: true, features: ['5 profissionais', '30 serviços', 'Agendamentos ilimitados', 'Tudo do Starter', 'Múltiplos profissionais', 'Comissionamento', 'Relatórios avançados', 'Personalização da marca'] }, { name: 'Business', price: 199.90, icon: Building2, color: '#a855f7', features: ['15 profissionais', '100 serviços', 'Agendamentos ilimitados', 'Tudo do Professional', 'API de integração', 'Suporte prioritário', 'Multi-unidades', 'Automações avançadas'] }, { name: 'Enterprise', price: 399.90, icon: Rocket, color: '#f59e0b', features: ['Profissionais ilimitados', 'Serviços ilimitados', 'Agendamentos ilimitados', 'Tudo do Business', 'Gerente dedicado', 'SLA garantido', 'Integrações customizadas', 'White-label'] }, ]; // Máscaras de entrada const formatCpfCnpj = (value: string) => { const v = value.replace(/\D/g, ''); if (v.length <= 11) { return v.replace(/(\d{3})(\d)/, '$1.$2') .replace(/(\d{3})(\d)/, '$1.$2') .replace(/(\d{3})(\d{1,2})$/, '$1-$2'); } return v.replace(/^(\d{2})(\d)/, '$1.$2') .replace(/^(\d{2})\.(\d{3})(\d)/, '$1.$2.$3') .replace(/\.(\d{3})(\d)/, '.$1/$2') .replace(/(\d{4})(\d)/, '$1-$2') .slice(0, 18); }; const formatPhone = (value: string) => { const v = value.replace(/\D/g, ''); return v.replace(/(\d{2})(\d)/, '($1) $2') .replace(/(\d{5})(\d)/, '$1-$2') .slice(0, 15); }; const formatCep = (value: string) => { const v = value.replace(/\D/g, ''); return v.replace(/(\d{5})(\d)/, '$1-$2') .slice(0, 9); }; const formatCardNumber = (value: string) => { const v = value.replace(/\D/g, ''); return v.replace(/(\d{4})(?=\d)/g, '$1 ').slice(0, 19); }; const formatExpiry = (value: string) => { const v = value.replace(/\D/g, ''); return v.replace(/(\d{2})(\d)/, '$1/$2').slice(0, 5); }; const formatCvv = (value: string) => { return value.replace(/\D/g, '').slice(0, 4); }; interface SubscriptionProps { currentPlan: string; onPlanChange: (newPlan: string) => void; isLocked?: boolean; onPaymentSuccess?: () => void; } export default function Subscription({ currentPlan, onPlanChange, isLocked = false, onPaymentSuccess }: SubscriptionProps) { const [selectedPlan, setSelectedPlan] = useState(null); const [paymentMethod, setPaymentMethod] = useState<'PIX' | 'BOLETO' | 'CREDIT_CARD'>('PIX'); const [loading, setLoading] = useState(false); const [successData, setSuccessData] = useState(null); const [errorMsg, setErrorMsg] = useState(null); const [dbPlans, setDbPlans] = useState([]); useEffect(() => { const fetchSubscriptionData = async () => { const slug = localStorage.getItem('agendapro_tenant_slug') || 'barbearia-premium'; try { const res = await fetch(`/api/tenant/subscription?slug=${slug}`); if (res.ok) { const data = await res.json(); if (data.plans && data.plans.length > 0) { setDbPlans(data.plans); } } } catch (e) { console.error('Erro ao buscar planos da API:', e); } }; fetchSubscriptionData(); }, []); const iconMap: Record = { Starter: Zap, Professional: Crown, Business: Building2, Enterprise: Rocket }; const colorMap: Record = { Starter: '#3b82f6', Professional: '#6C63FF', Business: '#a855f7', Enterprise: '#f59e0b' }; const plans = dbPlans.length > 0 ? dbPlans.map(p => { let featuresList: string[] = []; try { if (typeof p.features === 'string') featuresList = JSON.parse(p.features); else if (Array.isArray(p.features)) featuresList = p.features; } catch (e) {} return { id: p.id, name: p.name, price: Number(p.price || p.price_monthly || 0), icon: iconMap[p.name] || Crown, color: colorMap[p.name] || '#6C63FF', featured: p.name === 'Professional', features: featuresList.length > 0 ? featuresList : ['Agendamento online'] }; }) : staticPlans; // Form de cartão const [cardHolder, setCardHolder] = useState(''); const [cardNumber, setCardNumber] = useState(''); const [cardExpiry, setCardExpiry] = useState(''); const [cardCvv, setCardCvv] = useState(''); // Dados de Faturamento const [billingInfo, setBillingInfo] = useState({ name: '', cpfCnpj: '', phone: '', email: '', postalCode: '', addressNumber: '', }); const activePlanData = plans.find(p => p.name === currentPlan) || plans[1]; const handleOpenPayment = (plan: any) => { setSelectedPlan(plan); setSuccessData(null); setErrorMsg(null); }; const handlePay = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); setErrorMsg(null); const slug = localStorage.getItem('agendapro_tenant_slug') || 'barbearia-premium'; let creditCard = undefined; let creditCardHolderInfo = undefined; if (paymentMethod === 'CREDIT_CARD') { const [month, year] = cardExpiry.split('/'); creditCard = { holderName: cardHolder, number: cardNumber.replace(/\s/g, ''), expiryMonth: month || '12', expiryYear: year ? `20${year}` : '2030', ccv: cardCvv, }; creditCardHolderInfo = { name: cardHolder, email: `${slug}@agendapro.com`, cpfCnpj: '00000000000', postalCode: '01310000', addressNumber: '123', phone: '11999991234', }; } try { const res = await fetch('/api/tenant/subscription', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ slug, planName: selectedPlan.name, billingType: paymentMethod, billingInfo, creditCard, creditCardHolderInfo, }), }); const data = await res.json(); if (!res.ok) { throw new Error(data.error || 'Falha ao processar pagamento'); } setSuccessData(data); onPlanChange(selectedPlan.name); } catch (err: any) { console.error(err); setErrorMsg(err.message || 'Erro inesperado no servidor'); } finally { setLoading(false); } }; // Simulação de pagamento no Sandbox / Dev const handleSimulatePayment = async () => { setLoading(true); const slug = localStorage.getItem('agendapro_tenant_slug') || 'barbearia-premium'; // Configura o cookie e localStorage de homologação local localStorage.setItem('agendapro_subscription_status', 'active'); document.cookie = "agendapro_subscription_status=active; path=/; max-age=2592000"; try { const res = await fetch('/api/tenant/subscription/simulate', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ slug, status: 'active' }), }); alert('Pagamento simulado com sucesso! O sistema foi desbloqueado.'); setSelectedPlan(null); if (onPaymentSuccess) { onPaymentSuccess(); } } catch (err) { console.warn('Erro ao conectar com API de simulação, utilizando fallback local de homologação.', err); alert('Pagamento simulado localmente! O sistema foi desbloqueado (modo offline).'); setSelectedPlan(null); if (onPaymentSuccess) { onPaymentSuccess(); } } finally { setLoading(false); } }; return (
{/* BANNER DE BLOQUEIO */} {isLocked && (

Acesso Pendente / Bloqueado 🔒

Sua assinatura do AgendaPRO não está ativa. Para reativar seu acesso completo e continuar gerenciando seus agendamentos, clientes e equipe, escolha um plano abaixo e efetue o pagamento.

)} {/* PLANO ATUAL INFO */} {!isLocked && (

Plano {activePlanData.name}

Sua assinatura está ativa e regularizada.

R$ {activePlanData.price.toFixed(2).replace('.', ',')} /mês
Ativo
)}

Escolha o plano ideal

{plans.map(plan => { const Icon = plan.icon; const isActive = currentPlan === plan.name && !isLocked; return (
{plan.name}
R$ {plan.price.toFixed(2).replace('.', ',')} /mês
    {plan.features.map(f => (
  • {f}
  • ))}
); })}
{/* MODAL DE PAGAMENTO */} {selectedPlan && (
setSelectedPlan(null)}>
e.stopPropagation()} style={{ maxWidth: '500px' }}>

Assinar Plano {selectedPlan.name}

{!successData ? (
{/* Seleção de meio de pagamento */}
Plano: {selectedPlan.name} (Mensal)
Valor total: R$ {selectedPlan.price.toFixed(2).replace('.', ',')}
{/* Dados de Faturamento */}

Dados do Pagador

setBillingInfo({...billingInfo, name: e.target.value})} />
setBillingInfo({...billingInfo, cpfCnpj: formatCpfCnpj(e.target.value)})} />
setBillingInfo({...billingInfo, phone: formatPhone(e.target.value)})} />
setBillingInfo({...billingInfo, email: e.target.value})} />
{paymentMethod === 'CREDIT_CARD' && (
setBillingInfo({...billingInfo, postalCode: formatCep(e.target.value)})} />
setBillingInfo({...billingInfo, addressNumber: e.target.value})} />
)}
{/* Inputs específicos do Cartão */} {paymentMethod === 'CREDIT_CARD' && (
setCardHolder(e.target.value)} />
setCardNumber(formatCardNumber(e.target.value))} />
setCardExpiry(formatExpiry(e.target.value))} />
setCardCvv(formatCvv(e.target.value))} />
)} {errorMsg && (
⚠️ {errorMsg}
)}
) : ( /* RESPOSTA DE SUCESSO DE PAGAMENTO */
{paymentMethod === 'PIX' && successData.pixCode && (

Cobrança Pix Gerada!

Escaneie o QR Code abaixo com seu banco para efetuar o pagamento da assinatura.

{successData.pixQrCodeImage && (
QR Code Pix
)}
)} {paymentMethod === 'BOLETO' && (

Boleto Emitido com Sucesso!

O boleto de cobrança foi emitido. Você receberá um e-mail com as instruções, ou poderá realizar o pagamento usando o link do painel de controle.

)} {paymentMethod === 'CREDIT_CARD' && (

Transação Aprovada!

Sua assinatura do plano {selectedPlan.name} foi confirmada e está ativa. Obrigado!

)}
)}
{/* BARRA DE FERRAMENTAS DE SIMULAÇÃO (SANDBOX DEVELOPER MODE) */}
Modo Homologação Sandbox Ativo
)}
); }