
import React, { useMemo, useState } from 'react';
import { NotaFiscal, NFStatus } from '../types';
import ExclamationTriangleIcon from './icons/ExclamationTriangleIcon';
import ClipboardListIcon from './icons/ClipboardListIcon';
import BoxIcon from './icons/BoxIcon';
import CheckCircleIcon from './icons/CheckCircleIcon';
import UsersIcon from './icons/UsersIcon';

// Helper to check if an NF is overdue
const isOverdue = (nf: NotaFiscal): boolean => {
    if (nf.status !== NFStatus.PENDENTE) return false;
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    const [year, month, day] = nf.dataPrevisao.split('-').map(Number);
    const previsionDate = new Date(year, month - 1, day);
    return previsionDate < today;
};

// Helper to get week number from a date
const getWeek = (date: Date): number => {
    const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
    const dayNum = d.getUTCDay() || 7;
    d.setUTCDate(d.getUTCDate() + 4 - dayNum);
    const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
    return Math.ceil((((d.getTime() - yearStart.getTime()) / 86400000) + 1) / 7);
};

const getWeekLabel = (date: Date) => {
    return `Semana ${getWeek(date)}/${date.getFullYear().toString().slice(-2)}`;
};


// Main Component
const AnalyticsDashboard: React.FC<{ nfs: NotaFiscal[] }> = ({ nfs }) => {
    const [dateRange, setDateRange] = useState<{ start: string | null; end: string | null }>({ start: null, end: null });

    const stats = useMemo(() => {
        const filteredNfsByDate = nfs.filter(nf => {
            if (!dateRange.start && !dateRange.end) return true; // No filter applied
            if (dateRange.start && nf.dataEmissao < dateRange.start) return false;
            if (dateRange.end && nf.dataEmissao > dateRange.end) return false;
            return true;
        });

        const pendentes = filteredNfsByDate.filter(nf => nf.status === NFStatus.PENDENTE && !isOverdue(nf)).length;
        const atrasados = filteredNfsByDate.filter(isOverdue).length;
        const recebidos = filteredNfsByDate.filter(nf => nf.status === NFStatus.RECEBIDO).length;
        const conferidos = filteredNfsByDate.filter(nf => nf.status === NFStatus.CONFERIDO).length;
        
        const leadTimeNFs = filteredNfsByDate.filter(nf => nf.dataRecebimento && nf.dataConferencia);
        const totalLeadTimeDays = leadTimeNFs.reduce((acc, nf) => {
            const start = new Date(nf.dataRecebimento!).getTime();
            const end = new Date(nf.dataConferencia!).getTime();
            const diff = (end - start) / (1000 * 60 * 60 * 24);
            return acc + diff;
        }, 0);
        const avgLeadTime = leadTimeNFs.length > 0 ? (totalLeadTimeDays / leadTimeNFs.length).toFixed(1) : '0';

        const statusDistribution = [
            { label: NFStatus.PENDENTE, value: pendentes, color: 'bg-yellow-400', hex: '#FBBF24' },
            { label: 'Atrasado', value: atrasados, color: 'bg-red-400', hex: '#F87171' },
            { label: NFStatus.RECEBIDO, value: recebidos, color: 'bg-blue-400', hex: '#60A5FA' },
            { label: NFStatus.CONFERIDO, value: conferidos, color: 'bg-green-400', hex: '#4ADE80' },
        ];
        
        const weeklyData: { [week: string]: { recebimentos: number, volumes: number } } = {};
        filteredNfsByDate.filter(nf => nf.dataRecebimento).forEach(nf => {
            const weekLabel = getWeekLabel(new Date(nf.dataRecebimento!));
            if (!weeklyData[weekLabel]) {
                weeklyData[weekLabel] = { recebimentos: 0, volumes: 0 };
            }
            weeklyData[weekLabel].recebimentos++;
            weeklyData[weekLabel].volumes += nf.volumesRecebidos || 0;
        });
        
        const weeklyRecebimentos = Object.entries(weeklyData).map(([label, data]) => ({ label, value: data.recebimentos })).sort((a,b) => a.label.localeCompare(b.label)).slice(-8);
        const weeklyVolumes = Object.entries(weeklyData).map(([label, data]) => ({ label, value: data.volumes })).sort((a,b) => a.label.localeCompare(b.label)).slice(-8);

        const fornecedorCounts: { [name: string]: number } = {};
        filteredNfsByDate.forEach(nf => {
            fornecedorCounts[nf.fornecedor] = (fornecedorCounts[nf.fornecedor] || 0) + 1;
        });
        const topFornecedores = Object.entries(fornecedorCounts)
            .map(([label, value]) => ({ label, value }))
            .sort((a, b) => b.value - a.value)
            .slice(0, 5);

        return { pendentes, atrasados, recebidos, conferidos, avgLeadTime, statusDistribution, weeklyRecebimentos, weeklyVolumes, topFornecedores };
    }, [nfs, dateRange]);
    
    return (
        <div className="container mx-auto px-4 sm:px-6 lg:px-8 py-8 animate-fade-in-up">
            <div className="flex flex-col sm:flex-row gap-4 mb-8 items-center justify-between">
                <h2 className="text-3xl font-bold text-white mr-auto shrink-0">Dashboard de Análise</h2>
                <div className="flex flex-wrap items-center justify-end gap-x-4 gap-y-2">
                    <div className="flex items-center gap-2">
                        <label htmlFor="startDate" className="text-sm text-gray-400">De:</label>
                        <input 
                            type="date" 
                            id="startDate"
                            value={dateRange.start || ''}
                            onChange={e => setDateRange(prev => ({ ...prev, start: e.target.value }))}
                            className="bg-primary-dark/50 border border-primary-medium rounded-lg px-3 py-1.5 text-white focus:ring-2 focus:ring-primary-light transition"
                        />
                    </div>
                    <div className="flex items-center gap-2">
                        <label htmlFor="endDate" className="text-sm text-gray-400">Até:</label>
                        <input 
                            type="date" 
                            id="endDate"
                            value={dateRange.end || ''}
                            onChange={e => setDateRange(prev => ({ ...prev, end: e.target.value }))}
                            className="bg-primary-dark/50 border border-primary-medium rounded-lg px-3 py-1.5 text-white focus:ring-2 focus:ring-primary-light transition"
                        />
                    </div>
                    {(dateRange.start || dateRange.end) && (
                        <button
                            onClick={() => setDateRange({ start: null, end: null })}
                            className="px-4 py-1.5 rounded-lg text-sm font-semibold text-white bg-gray-600 hover:bg-gray-500 transition-colors"
                        >
                            Limpar
                        </button>
                    )}
                </div>
            </div>
            
            <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4 mb-8">
                <KPICard title="Pendentes" value={stats.pendentes} icon={<ClipboardListIcon className="w-8 h-8"/>} color="text-yellow-400" />
                <KPICard title="Atrasados" value={stats.atrasados} icon={<ExclamationTriangleIcon className="w-8 h-8"/>} color="text-red-400" />
                <KPICard title="Recebidos" value={stats.recebidos} icon={<BoxIcon className="w-8 h-8"/>} color="text-blue-400" />
                <KPICard title="Conferidos" value={stats.conferidos} icon={<CheckCircleIcon className="w-8 h-8"/>} color="text-green-400" />
                <KPICard title="Lead Time Médio (Rec-Conf)" value={`${stats.avgLeadTime} dias`} icon={<UsersIcon className="w-8 h-8"/>} color="text-primary-light" />
            </div>

            <div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
                <ChartContainer title="Recebimentos por Semana">
                    <BarChart data={stats.weeklyRecebimentos} color="bg-primary-light" />
                </ChartContainer>
                <ChartContainer title="Volumes Recebidos por Semana">
                    <BarChart data={stats.weeklyVolumes} color="bg-blue-400" />
                </ChartContainer>
                <ChartContainer title="Distribuição de Status">
                    <DonutChart data={stats.statusDistribution} />
                </ChartContainer>
                <ChartContainer title="Top 5 Fornecedores por NF">
                    <HorizontalBarChart data={stats.topFornecedores} />
                </ChartContainer>
            </div>
        </div>
    );
};


const KPICard: React.FC<{ title: string; value: string | number; icon: React.ReactNode; color: string }> = ({ title, value, icon, color }) => (
    <div className="bg-primary-medium/20 border border-primary-medium/50 rounded-2xl p-4 flex flex-col items-start justify-between">
        <div className={`p-2 bg-primary-dark/50 rounded-full ${color}`}>{icon}</div>
        <div>
            <p className="text-3xl font-bold text-white mt-2">{value}</p>
            <p className="text-sm text-gray-400">{title}</p>
        </div>
    </div>
);

const ChartContainer: React.FC<{ title: string; children: React.ReactNode }> = ({ title, children }) => (
    <div className="bg-primary-medium/20 border border-primary-medium/50 rounded-2xl p-6">
        <h3 className="text-xl font-bold text-white mb-4">{title}</h3>
        <div className="h-64">{children}</div>
    </div>
);

const BarChart: React.FC<{ data: { label: string, value: number }[], color: string }> = ({ data, color }) => {
    if (data.length === 0) return <div className="flex items-center justify-center h-full text-gray-500">Sem dados para exibir.</div>;
    const maxValue = Math.max(...data.map(d => d.value), 1);
    return (
        <div className="flex justify-around items-end h-full gap-2">
            {data.map(({ label, value }) => (
                <div key={label} className="flex flex-col items-center flex-1 h-full justify-end max-w-12">
                    <div className="text-sm font-bold text-white">{value}</div>
                    <div className={`${color} w-full rounded-t-md transition-all duration-500`} style={{ height: `${(value / maxValue) * 80}%` }}></div>
                    <div className="text-xs text-gray-400 mt-1 text-center truncate w-full">{label.replace('Semana ', 'S')}</div>
                </div>
            ))}
        </div>
    );
};

const DonutChart: React.FC<{ data: { label: string; value: number; color: string; hex: string }[] }> = ({ data }) => {
    if (data.every(d => d.value === 0)) return <div className="flex items-center justify-center h-full text-gray-500">Sem dados para exibir.</div>;

    const total = data.reduce((acc, item) => acc + item.value, 0);

    return (
        <div className="flex flex-col md:flex-row items-center justify-center h-full gap-8">
            <div className="relative w-40 h-40">
                <svg viewBox="0 0 36 36" className="w-full h-full transform -rotate-90">
                    {(() => {
                        let accumulated = 0;
                        return data.map((item, index) => {
                            const percentage = total === 0 ? 0 : (item.value / total) * 100;
                            const dash = `${percentage} ${100 - percentage}`;
                            const offset = -accumulated;
                            accumulated += percentage;
                            return (
                                <circle
                                    key={index}
                                    cx="18" cy="18" r="15.915"
                                    fill="transparent"
                                    strokeWidth="4"
                                    stroke={item.hex}
                                    strokeDasharray={dash}
                                    strokeDashoffset={offset}
                                />
                            );
                        });
                    })()}
                </svg>
                 <div className="absolute inset-0 flex items-center justify-center flex-col">
                    <span className="text-3xl font-bold text-white">{total}</span>
                    <span className="text-xs text-gray-400">Total</span>
                </div>
            </div>
            <div className="flex flex-col gap-2">
                {data.map((item, index) => (
                    <div key={index} className="flex items-center space-x-2">
                        <div className={`w-3 h-3 rounded-sm ${item.color}`}></div>
                        <span className="text-sm text-gray-300">{item.label}: <span className="font-bold text-white">{item.value}</span></span>
                    </div>
                ))}
            </div>
        </div>
    );
};

const HorizontalBarChart: React.FC<{ data: { label: string, value: number }[] }> = ({ data }) => {
    if (data.length === 0) return <div className="flex items-center justify-center h-full text-gray-500">Sem dados para exibir.</div>;
    const maxValue = Math.max(...data.map(d => d.value), 1);
    return (
        <div className="space-y-3 h-full flex flex-col justify-around">
            {data.map(({ label, value }) => (
                <div key={label} className="flex items-center gap-3">
                    <div className="text-sm text-gray-300 w-2/5 text-right truncate">{label}</div>
                    <div className="w-3/5 bg-primary-dark/50 rounded-full">
                         <div
                            className="bg-primary-light h-4 rounded-full text-xs text-primary-dark font-bold flex items-center justify-end pr-2"
                            style={{ width: `${(value / maxValue) * 100}%` }}
                         >
                            {value}
                        </div>
                    </div>
                </div>
            ))}
        </div>
    );
};

export default AnalyticsDashboard;
