"use client"; import { useState, useEffect, memo, useMemo, useCallback } from "react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { TrendingUp, TrendingDown, Package, DollarSign, AlertTriangle, RefreshCw, Calendar, BarChart3, Brain, Layers, Zap, Info, } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; import { Skeleton } from "@/components/ui/skeleton"; import { getPredictionsOverviewWithStore, getStockPredictionsWithStore, type PredictionsOverview, type StockPredictionsResponse, } from "@/lib/services/analytics-service"; import { formatGBP } from "@/utils/format"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { format } from "date-fns"; import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip as RechartsTooltip, ResponsiveContainer, } from "recharts"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; interface PredictionsChartProps { timeRange?: number; } export default function PredictionsChart({ timeRange = 90, }: PredictionsChartProps) { const [predictions, setPredictions] = useState( null, ); const [stockPredictions, setStockPredictions] = useState(null); const [loading, setLoading] = useState(true); const [daysAhead, setDaysAhead] = useState(7); const [activeTab, setActiveTab] = useState<"overview" | "stock">("overview"); const { toast } = useToast(); const fetchPredictions = async () => { try { setLoading(true); const [overview, stock] = await Promise.all([ getPredictionsOverviewWithStore(daysAhead, timeRange), getStockPredictionsWithStore(timeRange), ]); setPredictions(overview); setStockPredictions(stock); } catch (error) { console.error("Error fetching predictions:", error); toast({ title: "Error", description: "Failed to load predictions", variant: "destructive", }); } finally { setLoading(false); } }; useEffect(() => { fetchPredictions(); }, [daysAhead, timeRange]); const getConfidenceColor = (confidence: string) => { switch (confidence) { case "very_high": return "bg-emerald-600/20 text-emerald-700 dark:text-emerald-400 border-emerald-600/30"; case "high": return "bg-green-500/10 text-green-700 dark:text-green-400"; case "medium": return "bg-yellow-500/10 text-yellow-700 dark:text-yellow-400"; case "low": return "bg-red-500/10 text-red-700 dark:text-red-400"; default: return "bg-gray-500/10 text-gray-700 dark:text-gray-400"; } }; const getConfidenceLabel = (confidence: string) => { switch (confidence) { case "very_high": return "Very High"; case "high": return "High"; case "medium": return "Medium"; case "low": return "Low"; default: return confidence; } }; if (loading) { return (
); } if (!predictions) { return ( Predictions Forecast future sales, demand, and stock levels

No prediction data available. Need more historical data.

); } return (
Predictions & Forecasting {predictions.sales.aiModel?.used ? "AI neural network + statistical models for sales, demand, and inventory" : "AI-powered predictions for sales, demand, and inventory"}
{activeTab === "overview" && (
{/* Sales Predictions */}
Revenue Prediction {predictions.sales.predicted !== null ? (
{formatGBP(predictions.sales.predicted)}

Predicted daily average revenue for the next {daysAhead} days

{getConfidenceLabel(predictions.sales.confidence)} Confidence {predictions.sales.confidenceScore !== undefined && ( ({Math.round(predictions.sales.confidenceScore * 100)}%) )}

Based on data consistency, historical accuracy, and model agreement

{predictions.sales.aiModel?.used && ( 🤖 AI Powered {predictions.sales.aiModel.modelAccuracy !== undefined && ( ({Math.round(predictions.sales.aiModel.modelAccuracy * 100)}%) )}

Predictions generated using a Deep Learning Ensemble Model (TensorFlow.js)

)} {predictions.sales.trend && ( {predictions.sales.trend.direction === "up" && ( )} {predictions.sales.trend.direction === "down" && ( )} {predictions.sales.trend.direction === "up" ? "Trending Up" : predictions.sales.trend.direction === "down" ? "Trending Down" : "Stable"}

Direction of the recent sales trend (slope analysis)

)} Next {daysAhead} days
{predictions.sales.predictedOrders && (
~{Math.round(predictions.sales.predictedOrders)}{" "} orders
)} {!predictions.sales.confidenceIntervals && predictions.sales.minPrediction && predictions.sales.maxPrediction && (
Range: {formatGBP(predictions.sales.minPrediction)} -{" "} {formatGBP(predictions.sales.maxPrediction)}
)}
) : (
{predictions.sales.message || "Insufficient data for prediction"}
)}
{/* Model Intelligence Card */} Model Intelligence

Technical details about the active prediction model

Architecture Hybrid Ensemble (Deep Learning)

Combines LSTM Neural Networks with Statistical Methods (Holt-Winters, ARIMA)

{stockPredictions?.predictions && (
Features Multi-Feature Enabled
)}
Optimization Performance Tuned
Model automatically retrains with new sales data.
Prediction Accuracy Warning These predictions are estimates based on historical sales data. Actual results may vary due to external factors, market conditions, and unforeseen events. Use these insights as a guide, not a guarantee. {/* Daily Predictions Chart */} {predictions.sales.dailyPredictions && predictions.sales.dailyPredictions.length > 0 && ( Daily Revenue Forecast
({ ...d, formattedDate: format(new Date(d.date), "MMM d"), value: d.predicted }))} margin={{ top: 5, right: 10, left: 0, bottom: 0, }} > `£${value}`} /> [formatGBP(value), "Revenue"]} />
)}
)} {activeTab === "stock" && (
{stockPredictions && stockPredictions.predictions.length > 0 ? ( <>

{stockPredictions.totalProducts} products tracked

{stockPredictions.productsNeedingRestock > 0 && (

{stockPredictions.productsNeedingRestock} products need restocking soon

)}
Product Current Stock Days Until Out Estimated Date Confidence Status {stockPredictions.predictions.map((prediction) => ( {prediction.productName} {prediction.currentStock} {prediction.unitType} {prediction.prediction.daysUntilOutOfStock !== null ? (
{prediction.prediction.daysUntilOutOfStock} days
{prediction.prediction.optimisticDays !== null && prediction.prediction.pessimisticDays && (
{prediction.prediction.optimisticDays} -{" "} {prediction.prediction.pessimisticDays} days
)}
) : ( "N/A" )}
{prediction.prediction.estimatedDate ? (
{format( new Date( prediction.prediction.estimatedDate, ), "MMM d, yyyy", )}
{prediction.prediction.optimisticDate && prediction.prediction.pessimisticDate && (
{format( new Date( prediction.prediction.optimisticDate, ), "MMM d", )}{" "} -{" "} {format( new Date( prediction.prediction.pessimisticDate, ), "MMM d", )}
)}
) : ( "N/A" )}
{getConfidenceLabel(prediction.prediction.confidence)} {prediction.needsRestock ? ( Restock Soon ) : ( OK )}
))}
) : (

No stock predictions available

Enable stock tracking on products to get predictions

)}
)}
); }