'use client' import { useState, useEffect, useCallback } from 'react' import { useRouter, useSearchParams } from 'next/navigation' import { motion, AnimatePresence } from 'framer-motion' import { Select } from '@ciphera-net/ui' import { TRAFFIC_TIERS, PLAN_PRICES } from '@/lib/plans' import { COUNTRY_OPTIONS } from '@/lib/countries' import { calculateVAT, type VATResult } from '@/lib/api/billing' interface PlanSummaryProps { plan: string interval: string limit: number country: string vatId: string onCountryChange: (country: string) => void onVatIdChange: (vatId: string) => void } const inputClass = 'w-full rounded-lg border border-neutral-700 bg-neutral-800/50 px-3 py-2.5 text-sm text-white placeholder:text-neutral-500 focus:outline-none focus:ring-1 focus:ring-brand-orange focus:border-brand-orange transition-colors' /** Convert VIES ALL-CAPS text to title case (e.g. "SA SODIMAS" → "Sa Sodimas") */ function toTitleCase(s: string) { return s.replace(/\S+/g, (w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()) } export default function PlanSummary({ plan, interval, limit, country, vatId, onCountryChange, onVatIdChange }: PlanSummaryProps) { const router = useRouter() const searchParams = useSearchParams() const [currentInterval, setCurrentInterval] = useState(interval) const [vatResult, setVatResult] = useState(null) const [vatLoading, setVatLoading] = useState(false) const [verifiedVatId, setVerifiedVatId] = useState('') const monthlyCents = PLAN_PRICES[plan]?.[limit] || 0 const isYearly = currentInterval === 'year' const baseDisplay = isYearly ? (monthlyCents * 11) / 100 : monthlyCents / 100 const tierLabel = TRAFFIC_TIERS.find((t) => t.value === limit)?.label || `${(limit / 1000).toFixed(0)}k` const handleIntervalToggle = (newInterval: string) => { setCurrentInterval(newInterval) const params = new URLSearchParams(searchParams.toString()) params.set('interval', newInterval) router.replace(`/checkout?${params.toString()}`, { scroll: false }) } const fetchVAT = useCallback(async (c: string, v: string, iv: string) => { if (!c) { setVatResult(null); return } setVatLoading(true) try { const result = await calculateVAT({ plan_id: plan, interval: iv, limit, country: c, vat_id: v || undefined }) setVatResult(result) } catch { setVatResult(null) } finally { setVatLoading(false) } }, [plan, limit]) // Auto-fetch when country or interval changes (using the already-verified VAT ID if any) useEffect(() => { if (!country) { setVatResult(null); return } fetchVAT(country, verifiedVatId, currentInterval) }, [country, currentInterval, fetchVAT, verifiedVatId]) // Clear verified state when VAT ID input changes after a successful verification useEffect(() => { if (verifiedVatId !== '' && vatId !== verifiedVatId) { setVerifiedVatId('') // Re-fetch without VAT ID to show the 21% rate if (country) fetchVAT(country, '', currentInterval) } }, [vatId]) // eslint-disable-line react-hooks/exhaustive-deps const handleVerifyVatId = () => { if (!vatId || !country) return setVerifiedVatId(vatId) // useEffect on verifiedVatId will trigger the fetch } const isVatChecked = verifiedVatId !== '' && verifiedVatId === vatId const isVatValid = isVatChecked && !!vatResult?.company_name return (
{/* Plan name + interval toggle */}

{plan}

30-day trial
{(['month', 'year'] as const).map((iv) => ( ))}
{/* Country */}
onVatIdChange(e.target.value)} placeholder="e.g. DE123456789" className={inputClass} />
{/* Verified company info */} {isVatValid && vatResult?.company_name && (

{toTitleCase(vatResult.company_name)}

{vatResult.company_address && (

{toTitleCase(vatResult.company_address)}

)}
)} {isVatChecked && vatResult && !vatResult.vat_exempt && ( VAT ID could not be verified. 21% VAT will apply. )}
{/* Price breakdown */}
{!country ? (
€{isYearly ? (baseDisplay / 12).toFixed(2) : baseDisplay.toFixed(0)} /mo excl. VAT · {tierLabel} pageviews {isYearly && ( Save 1 month )}
) : vatLoading && !vatResult ? (
Calculating VAT...
) : vatResult ? (
Subtotal ({tierLabel} pageviews) €{vatResult.base_amount}
{vatResult.vat_exempt ? (
{vatResult.vat_reason} €0.00
) : (
VAT {vatResult.vat_rate}% €{vatResult.vat_amount}
)}
Total {isYearly ? '/year' : '/mo'} €{vatResult.total_amount}
{isYearly && (

€{(parseFloat(vatResult.total_amount) / 12).toFixed(2)}/mo

)}
) : null}
) }