import React, { useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Card, CardHeader, CardBody } from '../../ui/Card'; import { StatsGrid } from '../../ui/Stats'; import { Badge } from '../../ui/Badge'; import { Button } from '../../ui/Button'; import { Select } from '../../ui/Select'; import { Euro, TrendingUp, AlertTriangle, Target, Clock, Activity, Zap, Download } from 'lucide-react'; import { useCurrentTenant } from '../../../stores/tenant.store'; import { useProductionDashboard } from '../../../api'; export interface ProductionCostData { totalCost: number; laborCost: number; materialCost: number; overheadCost: number; energyCost: number; costPerUnit: number; budget: number; variance: number; trend: { direction: 'up' | 'down' | 'stable'; percentage: number; }; costHistory: Array<{ date: string; totalCost: number; laborCost: number; materialCost: number; overheadCost: number; energyCost: number; }>; } export interface ProductionCostAnalyticsProps { className?: string; data?: ProductionCostData; timeRange?: 'day' | 'week' | 'month' | 'quarter' | 'year'; onTimeRangeChange?: (range: 'day' | 'week' | 'month' | 'quarter' | 'year') => void; onViewDetails?: () => void; onOptimize?: () => void; onExport?: () => void; } const ProductionCostAnalytics: React.FC = ({ className, data, timeRange = 'month', onTimeRangeChange, onViewDetails, onOptimize, onExport }) => { const { t } = useTranslation(); const currentTenant = useCurrentTenant(); const tenantId = currentTenant?.id || ''; const { data: dashboardData, isLoading, error } = useProductionDashboard(tenantId); const [selectedTimeRange, setSelectedTimeRange] = useState<'day' | 'week' | 'month' | 'quarter' | 'year'>(timeRange); const costData = useMemo((): ProductionCostData => { if (data) return data; // Calculate from dashboard data if available if (dashboardData) { const mockData: ProductionCostData = { totalCost: 2840.50, laborCost: 1200.00, materialCost: 1450.00, overheadCost: 190.50, energyCost: 95.25, costPerUnit: 14.20, budget: 3000.00, variance: -159.50, trend: { direction: 'down', percentage: 5.3 }, costHistory: [ { date: '2024-01-16', totalCost: 2750.20, laborCost: 1150.00, materialCost: 1420.00, overheadCost: 180.20, energyCost: 90.00 }, { date: '2024-01-17', totalCost: 2780.80, laborCost: 1180.00, materialCost: 1430.00, overheadCost: 180.80, energyCost: 90.00 }, { date: '2024-01-18', totalCost: 2720.10, laborCost: 1120.00, materialCost: 1410.00, overheadCost: 190.10, energyCost: 100.00 }, { date: '2024-01-19', totalCost: 2810.60, laborCost: 1220.00, materialCost: 1440.00, overheadCost: 190.60, energyCost: 95.00 }, { date: '2024-01-20', totalCost: 2800.40, laborCost: 1210.00, materialCost: 1440.00, overheadCost: 180.40, energyCost: 90.00 }, { date: '2024-01-21', totalCost: 2790.30, laborCost: 1190.00, materialCost: 1430.00, overheadCost: 180.30, energyCost: 90.00 }, { date: '2024-01-22', totalCost: 2840.50, laborCost: 1200.00, materialCost: 1450.00, overheadCost: 190.50, energyCost: 95.25 } ] }; return mockData; } // Default mock data return { totalCost: 2840.50, laborCost: 1200.00, materialCost: 1450.00, overheadCost: 190.50, energyCost: 95.25, costPerUnit: 14.20, budget: 3000.00, variance: -159.50, trend: { direction: 'down', percentage: 5.3 }, costHistory: [ { date: '2024-01-16', totalCost: 2750.20, laborCost: 1150.00, materialCost: 1420.00, overheadCost: 180.20, energyCost: 90.00 }, { date: '2024-01-17', totalCost: 2780.80, laborCost: 1180.00, materialCost: 1430.00, overheadCost: 180.80, energyCost: 90.00 }, { date: '2024-01-18', totalCost: 2720.10, laborCost: 1120.00, materialCost: 1410.00, overheadCost: 190.10, energyCost: 100.00 }, { date: '2024-01-19', totalCost: 2810.60, laborCost: 1220.00, materialCost: 1440.00, overheadCost: 190.60, energyCost: 95.00 }, { date: '2024-01-20', totalCost: 2800.40, laborCost: 1210.00, materialCost: 1440.00, overheadCost: 180.40, energyCost: 90.00 }, { date: '2024-01-21', totalCost: 2790.30, laborCost: 1190.00, materialCost: 1430.00, overheadCost: 180.30, energyCost: 90.00 }, { date: '2024-01-22', totalCost: 2840.50, laborCost: 1200.00, materialCost: 1450.00, overheadCost: 190.50, energyCost: 95.25 } ] }; }, [data, dashboardData]); const formatCurrency = (amount: number) => { return new Intl.NumberFormat('es-ES', { style: 'currency', currency: 'EUR', minimumFractionDigits: 2 }).format(amount); }; const getVarianceColor = (variance: number) => { if (variance > 0) return 'text-red-600'; if (variance < -50) return 'text-green-600'; return 'text-yellow-600'; }; const getBudgetStatus = () => { const percentage = (costData.totalCost / costData.budget) * 100; if (percentage > 100) return { color: 'error', label: t('production.cost.over_budget', 'Over Budget') }; if (percentage > 90) return { color: 'warning', label: t('production.cost.near_budget', 'Near Budget') }; return { color: 'success', label: t('production.cost.on_budget', 'On Budget') }; }; const budgetStatus = getBudgetStatus(); const handleTimeRangeChange = (range: string) => { const newRange = range as 'day' | 'week' | 'month' | 'quarter' | 'year'; setSelectedTimeRange(newRange); onTimeRangeChange?.(newRange); }; if (isLoading) { return (

{t('production.cost.analytics.title', 'Cost Analytics')}

{t('production.cost.error', 'Error loading cost data')}

); } const costStats = [ { title: t('production.cost.total_cost', 'Total Cost'), value: formatCurrency(costData.totalCost), icon: Euro, variant: budgetStatus.color as 'success' | 'warning' | 'error', trend: { value: costData.trend.percentage, direction: costData.trend.direction === 'up' ? 'up' as const : 'down' as const, label: t('production.cost.vs_last_period', 'vs last period') }, subtitle: `${formatCurrency(Math.abs(costData.variance))} ${costData.variance > 0 ? t('common.over', 'over') : t('common.under', 'under')} ${t('common.budget', 'budget')}` }, { title: t('production.cost.cost_per_unit', 'Cost per Unit'), value: formatCurrency(costData.costPerUnit), icon: Target, variant: 'info' as const, subtitle: t('production.cost.average', 'Average for selected period') }, { title: t('production.cost.labor_cost', 'Labor Cost'), value: formatCurrency(costData.laborCost), icon: Clock, variant: 'default' as const, subtitle: `${((costData.laborCost / costData.totalCost) * 100).toFixed(1)}% of total` }, { title: t('production.cost.material_cost', 'Material Cost'), value: formatCurrency(costData.materialCost), icon: Activity, variant: 'default' as const, subtitle: `${((costData.materialCost / costData.totalCost) * 100).toFixed(1)}% of total` } ]; const costBreakdown = [ { label: t('production.cost.labor', 'Labor'), amount: costData.laborCost, percentage: (costData.laborCost / costData.totalCost) * 100, icon: Clock, color: 'bg-blue-500' }, { label: t('production.cost.materials', 'Materials'), amount: costData.materialCost, percentage: (costData.materialCost / costData.totalCost) * 100, icon: Activity, color: 'bg-green-500' }, { label: t('production.cost.overhead', 'Overhead'), amount: costData.overheadCost, percentage: (costData.overheadCost / costData.totalCost) * 100, icon: Euro, color: 'bg-orange-500' }, { label: t('production.cost.energy', 'Energy'), amount: costData.energyCost, percentage: (costData.energyCost / costData.totalCost) * 100, icon: Zap, color: 'bg-yellow-500' } ]; // Create a simple bar chart visualization for cost history const renderCostChart = () => { if (!costData.costHistory || costData.costHistory.length === 0) return null; // Find the maximum value for scaling const maxValue = Math.max(...costData.costHistory.map(item => item.totalCost)); return (
{formatCurrency(0)} {formatCurrency(maxValue)}
{costData.costHistory.map((item, index) => { const height = (item.totalCost / maxValue) * 100; return (
{new Date(item.date).toLocaleDateString('es-ES')}
{formatCurrency(item.totalCost)}
); })}
); }; return (

{t('production.cost.analytics.title', 'Cost Analytics')}

{t('production.cost.analytics.subtitle', 'Detailed cost breakdown and trends')}