"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"; 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.
{/* 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

)}
)}
); }