import { useQuery } from '@tanstack/react-query'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { DollarSign, TrendingUp, BarChart3, PieChart } from 'lucide-react'; import { supabase } from '@/integrations/supabase/client'; import { formatCurrency } from '@/lib/currency'; import { aggregateMultiCurrencyAmounts, convertToUSD } from '@/lib/currencyConverter'; import { ExportAnalysis } from './ExportAnalysis'; export function ReportsOverview() { const { data: summaryData, isLoading, error } = useQuery({ queryKey: ['reports-summary'], queryFn: async () => { console.log('Reports: Starting data fetch...'); // Get category breakdown - now we need to join with categories table const { data: services, error: servicesError } = await supabase .from('services') .select(` category_id, amount, billing_cycle, custom_cycle_days, status, currency, next_renewal_date, categories!inner(name) `) .eq('status', 'Active'); console.log('Reports: Services fetch result:', { services: services?.length, error: servicesError }); if (servicesError) { console.error('Reports: Error fetching services:', servicesError); throw servicesError; } if (!services) return null; // Calculate current month actual amounts (not average monthly) const currentDate = new Date(); const currentMonth = currentDate.getMonth(); const currentYear = currentDate.getFullYear(); const monthlyAmounts = services.map(service => { if (!service.next_renewal_date) return { amount: 0, currency: service.currency, category: service.categories?.name || 'Unknown' }; const nextRenewal = new Date(service.next_renewal_date); const renewalMonth = nextRenewal.getMonth(); const renewalYear = nextRenewal.getFullYear(); // Only count if renewal is due in current month/year if (renewalYear === currentYear && renewalMonth === currentMonth) { return { amount: service.amount, currency: service.currency, category: service.categories?.name || 'Unknown' }; } return { amount: 0, currency: service.currency, category: service.categories?.name || 'Unknown' }; }); // Aggregate totals by currency using the centralized converter const { convertedToUSD, convertedToINR, totals } = aggregateMultiCurrencyAmounts(monthlyAmounts); // Calculate category breakdown using the proper currency converter const categoryTotals = monthlyAmounts.reduce((acc, item) => { if (item.amount === 0) return acc; const categoryName = item.category; const usdAmount = item.currency === 'USD' ? item.amount : convertToUSD(item.amount, item.currency); acc[categoryName] = (acc[categoryName] || 0) + usdAmount; return acc; }, {} as Record); const topCategory = Object.entries(categoryTotals).sort(([,a], [,b]) => b - a)[0]; // Get payments for last 3 months trend const { data: payments, error: paymentsError } = await supabase .from('payments') .select('payment_date, amount, currency') .gte('payment_date', new Date(Date.now() - 90 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]) .order('payment_date'); console.log('Reports: Payments fetch result:', { payments: payments?.length, error: paymentsError }); if (paymentsError) { console.error('Reports: Error fetching payments:', paymentsError); // Don't throw error for payments, just use empty array } const paymentsAmounts = payments?.map(p => ({ amount: p.amount, currency: p.currency })) || []; const { convertedToINR: last3MonthsINR } = aggregateMultiCurrencyAmounts(paymentsAmounts); return { categoryBreakdown: Object.entries(categoryTotals).map(([category, amount]) => ({ category, amount: Math.round(amount), percentage: Math.round((amount / convertedToUSD) * 100) })).sort((a, b) => b.amount - a.amount), totalMonthlySpend: { usd: Math.round(convertedToUSD), inr: Math.round(convertedToINR) }, topCategory: topCategory ? { category: topCategory[0], amount: Math.round(topCategory[1]) } : null, last3MonthsTotal: Math.round(last3MonthsINR), serviceCount: services.length, currencyBreakdown: services.reduce((acc, service) => { acc[service.currency] = (acc[service.currency] || 0) + 1; return acc; }, {} as Record) }; }, }); console.log('Reports: Component render', { isLoading, hasError: !!error, hasData: !!summaryData }); if (error) { console.error('Reports: Query error:', error); return (

Error loading reports

{error.message}

); } if (isLoading) { return (
{[...Array(6)].map((_, i) => (
))}
); } if (!summaryData) { return (

No data available. Add some services to see reports.

); } return (
{/* Summary Cards */}
Monthly Spend
{formatCurrency(summaryData.totalMonthlySpend.inr, 'INR')}
{formatCurrency(summaryData.totalMonthlySpend.usd, 'USD')}

From {summaryData.serviceCount} active services

Top Category
{summaryData.topCategory?.category || 'N/A'}

{summaryData.topCategory && formatCurrency(summaryData.topCategory.amount)} monthly

Quarterly Spend
{formatCurrency(summaryData.last3MonthsTotal)}

Last 3 months actual payments

Categories
{summaryData.categoryBreakdown.length}

Different service types

{/* Category Breakdown */}
Spending by Category
{summaryData.categoryBreakdown.map((item) => (
{item.category} {item.percentage}%
{formatCurrency(item.amount)}
))}
Currency Distribution
{Object.entries(summaryData.currencyBreakdown).map(([currency, count]) => (
{currency}
{count} {count === 1 ? 'service' : 'services'}
))}
{/* Export Options */}
); }