'use client'
import { CheckCircleIcon, XCircleIcon, SparklesIcon, CreditCardIcon, ArrowTopRightOnSquareIcon } from '@heroicons/react/24/outline'
import { useSubscription } from '@/lib/hooks/useSubscription'
import { usePortalSession } from '@/lib/hooks/usePortalSession'
import DashboardLayout from '@/components/dashboard/DashboardLayout'
import { formatDate, formatPrice } from '@/lib/stripe'
import { useState, useEffect } from 'react'
import { useSearchParams } from 'next/navigation'
import Link from 'next/link'
export default function DashboardBillingPage() {
const {
subscription,
isActive,
isPastDue,
isCanceled,
willCancelAtPeriodEnd,
getCurrentPlan,
canManageBilling,
refreshAfterCheckout
} = useSubscription()
const { createPortalSession, loading: portalLoading } = usePortalSession()
const [isManaging, setIsManaging] = useState(false)
const searchParams = useSearchParams()
// Refresh subscription data if this is a successful checkout redirect
useEffect(() => {
const isSuccess = searchParams.get('success') === 'true'
if (isSuccess) {
console.log('Detected successful checkout, refreshing subscription data...')
refreshAfterCheckout()
}
}, [searchParams, refreshAfterCheckout])
const currentPlan = getCurrentPlan()
// Determine if this is annual billing based on price_id
const isAnnualBilling = subscription?.price_id ?
currentPlan?.pricing.annually.priceId === subscription.price_id : false
// Get the appropriate price to display
const getCurrentPrice = () => {
if (!currentPlan) return null
if (isAnnualBilling) {
return currentPlan.pricing.annually.price / 12 // Show monthly equivalent
}
return currentPlan.pricing.monthly.price
}
const getStatusBadge = () => {
if (isActive) {
return <span className="px-3 py-1 text-xs font-medium bg-emerald-500/20 text-emerald-300 border border-emerald-500/30 rounded-full backdrop-blur-sm">Active</span>
}
if (isPastDue) {
return <span className="px-3 py-1 text-xs font-medium bg-amber-500/20 text-amber-300 border border-amber-500/30 rounded-full backdrop-blur-sm">Past Due</span>
}
if (isCanceled) {
return <span className="px-3 py-1 text-xs font-medium bg-red-500/20 text-red-300 border border-red-500/30 rounded-full backdrop-blur-sm">Canceled</span>
}
return <span className="px-3 py-1 text-xs font-medium bg-gray-500/20 text-gray-300 border border-gray-500/30 rounded-full backdrop-blur-sm">Free</span>
}
const handleManageSubscription = async () => {
try {
console.log('Button clicked! Starting portal session...')
setIsManaging(true)
await createPortalSession()
console.log('Portal session completed successfully')
} catch (error) {
console.error('Failed to open customer portal:', error)
// Show user-friendly error
alert(`Error: ${error instanceof Error ? error.message : 'Unknown error occurred'}`)
} finally {
setIsManaging(false)
}
}
const currentPrice = getCurrentPrice()
return (
<DashboardLayout
title="Billing & Plans"
subtitle="Manage your subscription and billing information"
>
<div className="space-y-8">
{/* Current Plan */}
<div className="bg-gray-900/40 backdrop-blur-sm border border-gray-800/50 rounded-2xl overflow-hidden">
<div className="px-4 sm:px-6 lg:px-8 py-6 lg:py-8 bg-gradient-to-r from-teal-500/10 to-cyan-500/10 border-b border-gray-800/50">
<div className="flex flex-col space-y-4 lg:flex-row lg:items-center lg:justify-between lg:space-y-0">
<div className="flex flex-col space-y-4 sm:flex-row sm:items-center sm:space-y-0 sm:space-x-4 lg:space-x-6">
<div className="p-3 sm:p-4 bg-gradient-to-br from-teal-500/20 to-cyan-500/20 rounded-xl border border-teal-500/30 self-start">
<SparklesIcon className="h-6 w-6 sm:h-8 sm:w-8 text-teal-400" />
</div>
<div className="min-w-0 flex-1">
<h2 className="text-xl sm:text-2xl lg:text-3xl font-bold text-white mb-2">
{currentPlan ? currentPlan.name : 'Free Plan'}
</h2>
<div className="flex flex-col space-y-2 sm:flex-row sm:items-center sm:space-y-0 sm:space-x-3">
<span className="text-gray-300 text-sm sm:text-base">Your current subscription plan</span>
{getStatusBadge()}
</div>
{subscription?.current_period_end && (
<p className="text-gray-400 text-xs sm:text-sm mt-2">
{willCancelAtPeriodEnd ? 'Cancels' : 'Renews'} on {formatDate(subscription.current_period_end)}
{isAnnualBilling && <span className="ml-2 px-2 py-1 bg-teal-500/20 text-teal-300 rounded-md text-xs">(Annual Plan)</span>}
</p>
)}
</div>
</div>
<div className="flex flex-col items-start lg:items-end space-y-4">
{currentPrice ? (
<div className="text-left lg:text-right">
<span className="text-2xl sm:text-3xl lg:text-4xl font-bold text-white">{formatPrice(currentPrice)}</span>
<span className="text-gray-300 text-base sm:text-lg">/month</span>
{isAnnualBilling && (
<div className="text-xs sm:text-sm text-gray-400 mt-1">
({formatPrice(currentPlan!.pricing.annually.price)}/year)
</div>
)}
</div>
) : (
<div className="text-left lg:text-right">
<span className="text-2xl sm:text-3xl lg:text-4xl font-bold text-white">$0</span>
<span className="text-gray-300 text-base sm:text-lg">/month</span>
</div>
)}
<div className="flex flex-col sm:flex-row gap-3 w-full lg:w-auto">
<a
href="/pricing"
className="px-4 sm:px-6 py-2.5 sm:py-3 text-xs sm:text-sm font-medium text-white bg-gradient-to-r from-teal-500 to-cyan-500 hover:from-teal-600 hover:to-cyan-600 rounded-xl transition-all duration-200 shadow-lg hover:shadow-xl text-center"
>
{currentPlan ? 'Change Plan' : 'Upgrade Plan'}
</a>
{canManageBilling() && (
<button
onClick={handleManageSubscription}
disabled={isManaging || portalLoading}
className="px-4 sm:px-6 py-2.5 sm:py-3 text-xs sm:text-sm font-medium text-gray-300 bg-gray-800/50 hover:bg-gray-700/50 border border-gray-700/50 rounded-xl transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2"
>
<CreditCardIcon className="w-4 h-4" />
{isManaging || portalLoading ? 'Loading...' : 'Manage Subscription'}
<ArrowTopRightOnSquareIcon className="w-3 h-3" />
</button>
)}
</div>
</div>
</div>
</div>
{/* Subscription Details */}
{subscription && (
<div className="px-4 sm:px-6 lg:px-8 py-6 border-b border-gray-800/50">
<h3 className="text-lg font-semibold text-white mb-4">Subscription Details</h3>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div className="space-y-2">
<div className="text-sm text-gray-400">Billing Cycle</div>
<div className="text-white font-medium">
{isAnnualBilling ? 'Annual' : 'Monthly'}
</div>
</div>
<div className="space-y-2">
<div className="text-sm text-gray-400">Period Start</div>
<div className="text-white font-medium">
{formatDate(subscription.current_period_start)}
</div>
</div>
<div className="space-y-2">
<div className="text-sm text-gray-400">Period End</div>
<div className="text-white font-medium">
{formatDate(subscription.current_period_end)}
</div>
</div>
<div className="space-y-2">
<div className="text-sm text-gray-400">Status</div>
<div className="font-medium">
{getStatusBadge()}
</div>
</div>
</div>
</div>
)}
{/* Plan Features */}
<div className="px-4 sm:px-6 lg:px-8 py-6 lg:py-8">
<h3 className="text-lg sm:text-xl font-bold text-white mb-4 sm:mb-6">Plan Features</h3>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
{currentPlan ? (
currentPlan.features.map((feature, index) => (
<div key={index} className="flex items-center text-gray-300 text-sm sm:text-base">
<CheckCircleIcon className="w-4 h-4 sm:w-5 sm:h-5 mr-2 sm:mr-3 text-emerald-400 flex-shrink-0" />
<span>{feature}</span>
</div>
))
) : (
<>
<div className="flex items-center text-gray-300 text-sm sm:text-base">
<CheckCircleIcon className="w-4 h-4 sm:w-5 sm:h-5 mr-2 sm:mr-3 text-emerald-400 flex-shrink-0" />
<span>Unlimited writing projects</span>
</div>
<div className="flex items-center text-gray-300 text-sm sm:text-base">
<CheckCircleIcon className="w-4 h-4 sm:w-5 sm:h-5 mr-2 sm:mr-3 text-emerald-400 flex-shrink-0" />
<span>Basic AI assistance</span>
</div>
<div className="flex items-center text-gray-400 text-sm sm:text-base">
<XCircleIcon className="w-4 h-4 sm:w-5 sm:h-5 mr-2 sm:mr-3 text-gray-500 flex-shrink-0" />
<span>🧠 Smart AI features</span>
</div>
<div className="flex items-center text-gray-400 text-sm sm:text-base">
<XCircleIcon className="w-4 h-4 sm:w-5 sm:h-5 mr-2 sm:mr-3 text-gray-500 flex-shrink-0" />
<span>Priority support</span>
</div>
</>
)}
</div>
{/* Subscription Status Messages */}
{willCancelAtPeriodEnd && (
<div className="mt-6 sm:mt-8 p-4 sm:p-6 bg-amber-500/10 border border-amber-500/30 rounded-xl backdrop-blur-sm">
<h4 className="text-amber-300 font-semibold mb-2 flex items-center text-sm sm:text-base">
<XCircleIcon className="w-4 h-4 sm:w-5 sm:h-5 mr-2 flex-shrink-0" />
Subscription Ending
</h4>
<p className="text-amber-200 text-xs sm:text-sm">
Your subscription will end on {formatDate(subscription!.current_period_end)}.
You'll lose access to premium features after this date.
</p>
</div>
)}
{isPastDue && (
<div className="mt-6 sm:mt-8 p-4 sm:p-6 bg-red-500/10 border border-red-500/30 rounded-xl backdrop-blur-sm">
<h4 className="text-red-300 font-semibold mb-2 flex items-center text-sm sm:text-base">
<XCircleIcon className="w-4 h-4 sm:w-5 sm:h-5 mr-2 flex-shrink-0" />
Payment Issue
</h4>
<p className="text-red-200 text-xs sm:text-sm">
There's an issue with your payment method. Please update your payment information to continue using premium features.
</p>
</div>
)}
</div>
</div>
{/* Usage Link */}
<div className="bg-gray-900/40 backdrop-blur-sm border border-gray-800/50 rounded-2xl p-6">
<div className="flex items-center justify-between">
<div>
<h3 className="text-lg font-bold text-white mb-2">Usage Analytics</h3>
<p className="text-gray-400 text-sm">Track your AI model usage and consumption patterns</p>
</div>
<Link
href="/dashboard/usage"
className="px-4 py-2 text-sm font-medium text-teal-300 bg-teal-500/10 hover:bg-teal-500/20 border border-teal-500/30 rounded-lg transition-all duration-200 flex items-center gap-2"
>
View Usage Analytics →
</Link>
</div>
</div>
</div>
</DashboardLayout>
)
}