import React, { useEffect, useMemo, useState } from 'react';
import Layout from '../components/Layout';
import NotificationBanner from '../components/NotificationBanner';
import { api } from '../lib/api';
import { useAuth } from '../context/AuthContext';
import { useNavigate } from 'react-router-dom';
import StatusBadge from '../components/StatusBadge';
import { Plus, FolderOpen, Clock, Activity, CheckCircle2, ChevronLeft, ChevronRight, Calendar as CalendarIcon, Truck } from 'lucide-react';
import { isFolderUnread } from '../lib/seen';

function formatYMD(date) {
    const y = date.getFullYear();
    const m = String(date.getMonth() + 1).padStart(2, '0');
    const d = String(date.getDate()).padStart(2, '0');
    return `${y}-${m}-${d}`;
}

function MiniCalendar({ value, onChange, markedDates }) {
    const [view, setView] = useState(() => new Date(value));

    const monthLabel = view.toLocaleDateString('fr-FR', { month: 'long', year: 'numeric' });
    const firstDay = new Date(view.getFullYear(), view.getMonth(), 1);
    const startDay = (firstDay.getDay() + 6) % 7;
    const daysInMonth = new Date(view.getFullYear(), view.getMonth() + 1, 0).getDate();
    const cells = [];
    for (let i = 0; i < startDay; i++) cells.push(null);
    for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(view.getFullYear(), view.getMonth(), d));

    const todayYMD = formatYMD(new Date());
    const selectedYMD = formatYMD(value);

    return (
        <div className="rounded-lg border border-slate-200 bg-white p-4 sm:p-5">
            <div className="flex items-center justify-between mb-4 gap-2">
                <div className="flex items-center gap-2 min-w-0">
                    <CalendarIcon className="h-4 w-4 text-stef shrink-0" />
                    <h3 className="font-heading text-xs sm:text-sm font-bold uppercase tracking-wider text-slate-700 truncate">{monthLabel}</h3>
                </div>
                <div className="flex items-center gap-1 shrink-0">
                    <button
                        data-testid="cal-prev"
                        onClick={() => setView(new Date(view.getFullYear(), view.getMonth() - 1, 1))}
                        className="h-8 w-8 rounded-md hover:bg-slate-100 flex items-center justify-center text-slate-600">
                        <ChevronLeft className="h-4 w-4" />
                    </button>
                    <button
                        data-testid="cal-next"
                        onClick={() => setView(new Date(view.getFullYear(), view.getMonth() + 1, 1))}
                        className="h-8 w-8 rounded-md hover:bg-slate-100 flex items-center justify-center text-slate-600">
                        <ChevronRight className="h-4 w-4" />
                    </button>
                </div>
            </div>
            <div className="grid grid-cols-7 gap-1 text-center mb-1">
                {['L', 'M', 'M', 'J', 'V', 'S', 'D'].map((d, i) => (
                    <div key={i} className="text-[10px] font-bold uppercase tracking-wider text-slate-400 py-1">{d}</div>
                ))}
            </div>
            <div className="grid grid-cols-7 gap-1">
                {cells.map((cell, i) => {
                    if (!cell) return <div key={i} />;
                    const ymd = formatYMD(cell);
                    const isToday = ymd === todayYMD;
                    const isSelected = ymd === selectedYMD;
                    const isMarked = markedDates?.includes(ymd);
                    return (
                        <button
                            key={i}
                            data-testid={`cal-day-${ymd}`}
                            onClick={() => onChange(cell)}
                            className={`relative aspect-square min-h-[36px] rounded-md text-sm font-medium transition-all ${
                                isSelected
                                    ? 'bg-stef text-white shadow-sm'
                                    : isToday
                                        ? 'bg-stef/10 text-stef font-bold'
                                        : 'text-slate-700 hover:bg-slate-100'
                            }`}
                        >
                            {cell.getDate()}
                            {isMarked && !isSelected && (
                                <span className="absolute bottom-1 left-1/2 -translate-x-1/2 h-1 w-1 rounded-full bg-stef" />
                            )}
                        </button>
                    );
                })}
            </div>
        </div>
    );
}

function StatCard({ icon: Icon, label, value, accent, testid }) {
    return (
        <div data-testid={testid} className="rounded-lg border border-slate-200 bg-white p-4 sm:p-5 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md">
            <div className="flex items-center justify-between">
                <div className="flex h-9 w-9 sm:h-10 sm:w-10 items-center justify-center rounded-md" style={{ backgroundColor: accent.bg, color: accent.fg }}>
                    <Icon className="h-4 w-4 sm:h-5 sm:w-5" />
                </div>
            </div>
            <p className="mt-3 sm:mt-4 font-heading text-3xl sm:text-4xl font-black text-slate-900 leading-none">{value}</p>
            <p className="mt-2 text-[10px] sm:text-xs font-bold uppercase tracking-[0.15em] sm:tracking-[0.2em] text-slate-500">{label}</p>
        </div>
    );
}

function FolderCard({ folder, onClick }) {
    const unread = isFolderUnread(folder);
    return (
        <div
            data-testid={`folder-card-${folder.id}`}
            onClick={onClick}
            className={`cursor-pointer rounded-lg border bg-white p-4 sm:p-5 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md ${unread ? 'border-stef/60 ring-2 ring-stef/10' : 'border-slate-200 hover:border-stef/40'}`}
        >
            <div className="flex items-start gap-3 sm:gap-4">
                {folder.preview ? (
                    <img src={folder.preview} alt="" className="h-16 w-16 sm:h-20 sm:w-20 rounded-md object-cover border border-slate-200 shrink-0" />
                ) : (
                    <div className="h-16 w-16 sm:h-20 sm:w-20 rounded-md bg-slate-100 border border-slate-200 flex items-center justify-center shrink-0">
                        <Truck className="h-5 w-5 sm:h-6 sm:w-6 text-slate-400" />
                    </div>
                )}
                <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2 flex-wrap">
                        <span className="font-heading text-base sm:text-lg font-black tracking-tight text-slate-900">{folder.plate}</span>
                        <StatusBadge status={folder.status} size="sm" />
                        {unread && (
                            <span data-testid={`folder-unread-${folder.id}`} className="inline-flex items-center gap-1 rounded-full bg-stef text-white px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider">
                                <span className="h-1.5 w-1.5 rounded-full bg-white animate-pulse" />Nouveau
                            </span>
                        )}
                    </div>
                    <p className="mt-1 sm:mt-1.5 text-sm text-slate-600 line-clamp-2">{folder.problem}</p>
                    <div className="mt-2 flex items-center gap-2 sm:gap-3 text-xs text-slate-500 flex-wrap">
                        <span>par <strong className="text-slate-700">{folder.cariste_name}</strong></span>
                        <span className="hidden sm:inline">·</span>
                        <span>{folder.photos_count} photo{folder.photos_count > 1 ? 's' : ''}</span>
                        {folder.assigned_to_name && (
                            <>
                                <span className="hidden sm:inline">·</span>
                                <span className="hidden sm:inline">traité par <strong className="text-stef">{folder.assigned_to_name}</strong></span>
                            </>
                        )}
                    </div>
                </div>
                <div className="text-right shrink-0">
                    <p className="text-xs text-slate-400">{new Date(folder.created_at).toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' })}</p>
                </div>
            </div>
        </div>
    );
}

export default function Dashboard() {
    const { user } = useAuth();
    const navigate = useNavigate();
    const [selectedDate, setSelectedDate] = useState(new Date());
    const [folders, setFolders] = useState([]);
    const [stats, setStats] = useState({ total: 0, waiting: 0, in_progress: 0, closed: 0 });
    const [markedDates, setMarkedDates] = useState([]);
    const [loading, setLoading] = useState(true);

    const dateKey = useMemo(() => formatYMD(selectedDate), [selectedDate]);
    const isBureau = user?.role === 'bureau';
    const [bureauFilter, setBureauFilter] = useState('all'); // all | waiting | in_progress | mine

    const load = async () => {
        setLoading(true);
        try {
            const [fRes, sRes, dRes] = await Promise.all([
                api.get('/folders', { params: { date: dateKey } }),
                api.get('/folders/stats', { params: { date: dateKey } }),
                api.get('/folders/dates'),
            ]);
            setFolders(fRes.data);
            setStats(sRes.data);
            setMarkedDates(dRes.data.dates || []);
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => { load(); /* eslint-disable-next-line */ }, [dateKey]);

    useEffect(() => {
        const handler = () => load();
        window.addEventListener('folder-refresh', handler);
        return () => window.removeEventListener('folder-refresh', handler);
        // eslint-disable-next-line
    }, [dateKey]);

    return (
        <Layout>
            <NotificationBanner />
            {/* Header */}
            <div className="flex items-start justify-between gap-3 mb-6 sm:mb-8 flex-wrap">
                <div className="min-w-0 flex-1">
                    <p className="text-xs font-bold uppercase tracking-[0.2em] text-stef">Tableau de bord</p>
                    <h1 className="mt-2 font-heading text-2xl sm:text-3xl lg:text-4xl font-black tracking-tight text-slate-900 break-words">
                        Bonjour {user?.fullname || user?.username}
                    </h1>
                    <p className="mt-1.5 text-sm sm:text-base text-slate-600">
                        {isBureau ? 'Tous les signalements des caristes.' : 'Vos signalements et leur suivi.'}
                    </p>
                </div>
                <button
                    data-testid="new-folder-btn"
                    onClick={() => navigate('/new-folder')}
                    className="inline-flex items-center gap-2 rounded-md bg-stef px-4 sm:px-5 h-11 sm:h-12 text-sm font-heading font-bold text-white hover:bg-stef-hover transition-all active:scale-[0.98] shadow-sm shrink-0"
                >
                    <Plus className="h-4 w-4" />
                    <span className="hidden sm:inline">Nouveau dossier</span>
                    <span className="sm:hidden">Nouveau</span>
                </button>
            </div>

            {/* Stats */}
            <div className="grid grid-cols-2 lg:grid-cols-4 gap-3 sm:gap-4">
                <StatCard testid="stat-total" icon={FolderOpen} label="Dossiers" value={stats.total} accent={{ bg: '#E0F2FE', fg: '#0050E6' }} />
                <StatCard testid="stat-waiting" icon={Clock} label="En attente" value={stats.waiting} accent={{ bg: '#FEF3C7', fg: '#B45309' }} />
                <StatCard testid="stat-progress" icon={Activity} label="En cours" value={stats.in_progress} accent={{ bg: '#E0F2FE', fg: '#0369A1' }} />
                <StatCard testid="stat-closed" icon={CheckCircle2} label="Clôturés" value={stats.closed} accent={{ bg: '#D1FAE5', fg: '#047857' }} />
            </div>

            {/* Calendar + list — Calendrier uniquement pour bureau */}
            <div className={`mt-6 sm:mt-8 grid grid-cols-1 gap-4 sm:gap-6 ${isBureau ? 'lg:grid-cols-3' : ''}`}>
                {isBureau && (
                    <div className="lg:col-span-1 space-y-4">
                        <MiniCalendar value={selectedDate} onChange={setSelectedDate} markedDates={markedDates} />
                        <div className="rounded-lg border border-slate-200 bg-white p-4 sm:p-5">
                            <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-500">Jour sélectionné</p>
                            <p className="mt-2 font-heading text-lg sm:text-2xl font-black text-stef leading-tight">
                                {selectedDate.toLocaleDateString('fr-FR', { weekday: 'long', day: 'numeric', month: 'long' })}
                            </p>
                            <p className="mt-1 text-sm text-slate-600">{folders.length} dossier{folders.length > 1 ? 's' : ''}</p>
                        </div>
                    </div>
                )}

                <div className={isBureau ? 'lg:col-span-2' : ''}>
                    <div className="flex items-center justify-between mb-3 flex-wrap gap-3">
                        <h2 className="font-heading text-lg sm:text-xl font-bold text-slate-900">Dossiers du jour</h2>
                    </div>

                    {isBureau && (
                        <div className="mb-3 flex items-center gap-2 flex-wrap" data-testid="bureau-filter">
                            {[
                                { id: 'all', label: 'Tous', count: folders.length },
                                { id: 'waiting', label: 'À traiter', count: folders.filter(f => f.status === 'en_attente').length },
                                { id: 'in_progress', label: 'En cours', count: folders.filter(f => f.status === 'en_cours').length },
                                { id: 'mine', label: 'Mes dossiers', count: folders.filter(f => f.assigned_to_id === user?.id).length },
                            ].map((f) => (
                                <button
                                    key={f.id}
                                    data-testid={`bureau-filter-${f.id}`}
                                    onClick={() => setBureauFilter(f.id)}
                                    className={`inline-flex items-center gap-2 rounded-full border px-3.5 h-9 text-xs font-heading font-bold uppercase tracking-wider transition ${
                                        bureauFilter === f.id
                                            ? 'bg-stef text-white border-stef'
                                            : 'bg-white text-slate-700 border-slate-300 hover:border-stef hover:text-stef'
                                    }`}
                                >
                                    {f.label}
                                    <span className={`inline-flex items-center justify-center rounded-full px-1.5 h-5 text-[10px] font-bold ${
                                        bureauFilter === f.id ? 'bg-white/20 text-white' : 'bg-slate-100 text-slate-600'
                                    }`}>{f.count}</span>
                                </button>
                            ))}
                        </div>
                    )}

                    {(() => {
                        const list = !isBureau ? folders : folders.filter((f) => {
                            if (bureauFilter === 'waiting') return f.status === 'en_attente';
                            if (bureauFilter === 'in_progress') return f.status === 'en_cours';
                            if (bureauFilter === 'mine') return f.assigned_to_id === user?.id;
                            return true;
                        });
                        if (loading) return (<div className="rounded-lg border border-slate-200 bg-white p-12 text-center text-slate-500">Chargement…</div>);
                        if (list.length === 0) return (
                            <div className="rounded-lg border border-dashed border-slate-300 bg-white p-8 sm:p-12 text-center">
                                <div className="mx-auto h-12 w-12 rounded-md bg-slate-100 flex items-center justify-center mb-3">
                                    <FolderOpen className="h-6 w-6 text-slate-400" />
                                </div>
                                <p className="font-heading font-bold text-slate-700">Aucun dossier pour cette date</p>
                                <p className="mt-1 text-sm text-slate-500">Les signalements créés apparaîtront ici.</p>
                            </div>
                        );
                        return (
                            <div className="space-y-3" data-testid="folders-list">
                                {list.map((f) => (
                                    <FolderCard key={f.id} folder={f} onClick={() => navigate(`/folders/${f.id}`)} />
                                ))}
                            </div>
                        );
                    })()}
                </div>
            </div>

            {/* Floating "+" mobile only */}
            <button
                data-testid="new-folder-fab"
                onClick={() => navigate('/new-folder')}
                aria-label="Nouveau dossier"
                className="lg:hidden fixed bottom-5 right-5 z-30 h-14 w-14 rounded-full bg-stef text-white shadow-lg shadow-stef/30 flex items-center justify-center active:scale-95 hover:bg-stef-hover transition-all"
            >
                <Plus className="h-7 w-7" />
            </button>
        </Layout>
    );
}
