"use client";

import { useState } from "react";
import { useSearchParams, useRouter, usePathname } from "next/navigation";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { EVENT_CONFIG, EventType, formatDuration } from "@/lib/event-config";
import { EventIcon } from "@/components/event-icon";
import { useBaby } from "@/contexts/baby-context";
import { format, isToday, isYesterday } from "date-fns";
import { fr } from "date-fns/locale";
import { Trash2, StickyNote, Pencil, CheckSquare, Square, XCircle, ImageIcon, Copy } from "lucide-react";
import Image from "next/image";
import { EventModal } from "@/components/event-modal";

interface Event {
  id: string;
  type: EventType;
  startedAt: string;
  endedAt?: string;
  notes?: string;
  metadata?: Record<string, unknown>;
  user: { id: string; name: string };
}

const PAGE_SIZE = 50;

function groupByDay(events: Event[]): Record<string, Event[]> {
  const groups: Record<string, Event[]> = {};
  for (const ev of events) {
    const key = format(new Date(ev.startedAt), "yyyy-MM-dd");
    if (!groups[key]) groups[key] = [];
    groups[key].push(ev);
  }
  return groups;
}

function dayLabel(key: string): string {
  const d = new Date(key);
  if (isToday(d)) return "Aujourd'hui";
  if (isYesterday(d)) return "Hier";
  return format(d, "EEEE d MMMM", { locale: fr });
}

function getEventSummary(event: Event): string {
  const meta = event.metadata ?? {};
  if (event.type === "BREASTFEED") {
    const side = meta.breastSide === "left" ? "gauche" : meta.breastSide === "right" ? "droite" : "les deux";
    if (event.endedAt) return `${formatDuration(new Date(event.startedAt), new Date(event.endedAt))} · ${side}`;
    return side;
  }
  if (event.type === "BOTTLE") return [meta.volume ? `${meta.volume} mL` : "", meta.bottleType === "maternal" ? "maternel" : "artificiel"].filter(Boolean).join(" · ");
  if (event.type === "PUMP") {
    const side = meta.side === "left" ? "gauche" : meta.side === "right" ? "droite" : "les deux";
    const parts = [meta.volume ? `${meta.volume} mL` : "", side];
    if (event.endedAt) parts.unshift(formatDuration(new Date(event.startedAt), new Date(event.endedAt)));
    return parts.filter(Boolean).join(" · ");
  }
  if (event.type === "DIAPER_STOOL") return [String(meta.color ?? ""), meta.leaked ? "débordement" : ""].filter(Boolean).join(" · ");
  if (event.type === "DIAPER_WET") return meta.leaked ? "débordement" : "";
  if (event.type === "TEMPERATURE") return meta.value ? `${meta.value}°${meta.unit ?? "C"}` : "";
  if (event.type === "MEDICATION") return String(meta.name ?? "");
  if (event.type === "SYMPTOM") {
    const tags = (meta.tags as string[] | undefined) ?? [];
    return tags.length > 0 ? tags.join(", ") : "";
  }
  if ((event.type === "NAP" || event.type === "NIGHT_SLEEP") && event.endedAt) {
    return formatDuration(new Date(event.startedAt), new Date(event.endedAt));
  }
  if (event.type === "OTHER") return event.notes ? event.notes.slice(0, 50) : "";
  return "";
}

export default function TimelinePage() {
  const qc = useQueryClient();
  const { selectedBaby } = useBaby();
  const [expandedId, setExpandedId] = useState<string | null>(null);
  const [editingNotes, setEditingNotes] = useState<{ id: string; notes: string } | null>(null);
  const [editingEvent, setEditingEvent] = useState<Event | null>(null);
  const [savedNoteId, setSavedNoteId] = useState<string | null>(null);
  const searchParams = useSearchParams();
  const router = useRouter();
  const pathname = usePathname();
  const filterType = (searchParams.get("type") as EventType | null) ?? "";
  const [page, setPage] = useState(0);
  const [selectMode, setSelectMode] = useState(false);
  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [duplicating, setDuplicating] = useState<string | null>(null); // sourceDate being duplicated
  const [dupTarget, setDupTarget] = useState(""); // target date string
  const [dupLoading, setDupLoading] = useState(false);
  const [dupError, setDupError] = useState("");

  const { data: eventsData, isLoading } = useQuery({
    queryKey: ["events", selectedBaby?.id, filterType, page],
    queryFn: () =>
      fetch(`/api/events?babyId=${selectedBaby!.id}&limit=${PAGE_SIZE}&offset=${page * PAGE_SIZE}${filterType ? `&type=${filterType}` : ""}`).then(
        (r) => r.json()
      ),
    enabled: !!selectedBaby?.id,
    refetchInterval: 10_000,
  });

  const events: Event[] = eventsData?.events ?? [];
  const total: number = eventsData?.total ?? 0;
  const hasMore = (page + 1) * PAGE_SIZE < total;

  const grouped = groupByDay(events);
  const days = Object.keys(grouped).sort((a, b) => b.localeCompare(a));

  async function deleteEvent(id: string) {
    await fetch(`/api/events/${id}`, { method: "DELETE" });
    qc.invalidateQueries({ queryKey: ["events"] });
  }

  async function duplicateDay(sourceDate: string, targetDate: string) {
    if (!selectedBaby?.id) return;
    setDupLoading(true);
    setDupError("");
    const res = await fetch("/api/events/duplicate-day", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ babyId: selectedBaby.id, sourceDate, targetDate }),
    });
    setDupLoading(false);
    if (!res.ok) {
      const data = await res.json();
      setDupError(data.error ?? "Erreur");
      return;
    }
    setDuplicating(null);
    setDupTarget("");
    setDupError("");
    qc.invalidateQueries({ queryKey: ["events"] });
  }

  async function deleteSelected() {
    if (selected.size === 0) return;
    await Promise.all([...selected].map((id) => fetch(`/api/events/${id}`, { method: "DELETE" })));
    setSelected(new Set());
    setSelectMode(false);
    qc.invalidateQueries({ queryKey: ["events"] });
  }

  function toggleSelect(id: string) {
    setSelected((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      return next;
    });
  }

  async function saveNotes(id: string, notes: string) {
    await fetch(`/api/events/${id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ notes }),
    });
    qc.invalidateQueries({ queryKey: ["events"] });
    setEditingNotes(null);
    setSavedNoteId(id);
    setTimeout(() => setSavedNoteId(null), 2000);
  }

  function handleFilterChange(t: EventType | "") {
    const params = new URLSearchParams(searchParams.toString());
    if (t === "" || t === filterType) { params.delete("type"); } else { params.set("type", t); }
    router.replace(`${pathname}?${params.toString()}`, { scroll: false });
    setPage(0);
  }

  return (
    <div className="p-4 md:p-8 pb-24 md:pb-8">
      <div className="mb-6">
        <div className="flex items-center justify-between mb-4">
          <h1 className="text-2xl font-bold text-slate-900 dark:text-slate-100">
            Journal{selectedBaby ? ` — ${selectedBaby.name}` : ""}
          </h1>
          <button
            onClick={() => { setSelectMode((v) => !v); setSelected(new Set()); }}
            className={`flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-medium border transition ${
              selectMode
                ? "bg-indigo-600 text-white border-indigo-600"
                : "bg-white dark:bg-slate-800 text-slate-600 dark:text-slate-300 border-slate-200 dark:border-slate-600"
            }`}
          >
            <CheckSquare className="w-3.5 h-3.5" />
            {selectMode ? "Annuler" : "Sélectionner"}
          </button>
        </div>
        {/* Filter chips */}
        <div className="sticky top-0 z-10 bg-white dark:bg-slate-900 -mx-4 px-4 py-2 border-b border-slate-100 dark:border-slate-800">
        <div className="flex gap-2 overflow-x-auto no-scrollbar">
          <button
            onClick={() => handleFilterChange("")}
            className={`flex-shrink-0 px-3 py-1.5 rounded-full text-xs font-medium transition border ${
              filterType === "" ? "bg-indigo-600 text-white border-indigo-600" : "bg-white dark:bg-slate-800 text-slate-600 dark:text-slate-300 border-slate-200 dark:border-slate-600 hover:border-slate-300 dark:hover:border-slate-500"
            }`}
          >
            Tout {total > 0 && <span className="opacity-70 ml-0.5">({total})</span>}
          </button>
          {(Object.keys(EVENT_CONFIG) as EventType[]).map((t) => (
            <button
              key={t}
              onClick={() => handleFilterChange(filterType === t ? "" : t)}
              className={`flex-shrink-0 flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-medium transition border ${
                filterType === t ? "bg-indigo-600 text-white border-indigo-600" : "bg-white dark:bg-slate-800 text-slate-600 dark:text-slate-300 border-slate-200 dark:border-slate-600 hover:border-slate-300 dark:hover:border-slate-500"
              }`}
            >
              <EventIcon name={EVENT_CONFIG[t].icon} className={`w-3 h-3 ${filterType === t ? "text-white" : EVENT_CONFIG[t].colorClass}`} />
              {EVENT_CONFIG[t].label}
            </button>
          ))}
        </div>
        </div>
      </div>

      {selectMode && (
        <div className="flex items-center justify-between mb-4 px-4 py-2.5 bg-indigo-50 dark:bg-indigo-950/50 border border-indigo-200 dark:border-indigo-800 rounded-xl">
          <span className="text-sm text-indigo-700 dark:text-indigo-300 font-medium">
            {selected.size} sélectionné{selected.size > 1 ? "s" : ""}
          </span>
          <div className="flex gap-2">
            <button
              onClick={() => { setSelectMode(false); setSelected(new Set()); }}
              className="flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-lg border border-slate-200 dark:border-slate-600 text-slate-600 dark:text-slate-300 bg-white dark:bg-slate-800"
            >
              <XCircle className="w-3.5 h-3.5" />
              Annuler
            </button>
            <button
              onClick={() => { if (confirm(`Supprimer ${selected.size} événement${selected.size > 1 ? "s" : ""} ?`)) deleteSelected(); }}
              disabled={selected.size === 0}
              className="flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-lg bg-red-600 text-white font-medium disabled:opacity-40"
            >
              <Trash2 className="w-3.5 h-3.5" />
              Supprimer ({selected.size})
            </button>
          </div>
        </div>
      )}

      {isLoading && (
        <div className="space-y-6">
          {[1, 2, 3].map((g) => (
            <div key={g}>
              <div className="h-3 w-24 bg-slate-200 dark:bg-slate-700 rounded animate-pulse mb-3" />
              <div className="bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden divide-y divide-slate-100 dark:divide-slate-700">
                {[1, 2, 3, 4].map((r) => (
                  <div key={r} className="flex items-center gap-3 px-4 py-3">
                    <div className="w-8 h-8 rounded-lg bg-slate-200 dark:bg-slate-700 animate-pulse flex-shrink-0" />
                    <div className="flex-1 space-y-1.5">
                      <div className="h-3 w-28 bg-slate-200 dark:bg-slate-700 rounded animate-pulse" />
                      <div className="h-2.5 w-16 bg-slate-100 dark:bg-slate-800 rounded animate-pulse" />
                    </div>
                    <div className="h-3 w-10 bg-slate-200 dark:bg-slate-700 rounded animate-pulse" />
                  </div>
                ))}
              </div>
            </div>
          ))}
        </div>
      )}

      <div className="space-y-6">
        {days.map((day) => (
          <div key={day}>
            <div className="flex items-center gap-3 mb-3">
              <span className="text-xs font-semibold text-slate-500 dark:text-slate-400 uppercase tracking-wide capitalize">{dayLabel(day)}</span>
              <div className="flex-1 h-px bg-slate-200 dark:bg-slate-700" />
              <span className="text-xs text-slate-400 dark:text-slate-500">{grouped[day].length}</span>
              {!selectMode && (
                <button
                  onClick={() => { setDuplicating(day); setDupTarget(""); setDupError(""); }}
                  title="Dupliquer ce jour"
                  className="p-1 rounded-lg text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 hover:bg-slate-100 dark:hover:bg-slate-800 transition"
                >
                  <Copy className="w-3.5 h-3.5" />
                </button>
              )}
            </div>

            {duplicating === day && (
              <div className="mb-3 px-4 py-3 bg-indigo-50 dark:bg-indigo-950/40 border border-indigo-200 dark:border-indigo-800 rounded-xl">
                <p className="text-xs font-medium text-indigo-700 dark:text-indigo-300 mb-2">
                  Copier les {grouped[day].length} événements vers…
                </p>
                <div className="flex items-center gap-2">
                  <input
                    type="date"
                    value={dupTarget}
                    onChange={(e) => { setDupTarget(e.target.value); setDupError(""); }}
                    min={format(new Date(), "yyyy-MM-dd")}
                    className="flex-1 px-3 py-1.5 text-sm rounded-lg border border-indigo-200 dark:border-indigo-700 bg-white dark:bg-slate-800 text-slate-900 dark:text-slate-100 focus:outline-none focus:ring-2 focus:ring-indigo-400"
                  />
                  <button
                    disabled={!dupTarget || dupLoading}
                    onClick={() => duplicateDay(day, dupTarget)}
                    className="px-3 py-1.5 text-xs font-medium bg-indigo-600 hover:bg-indigo-700 disabled:bg-indigo-300 dark:disabled:bg-indigo-900 text-white rounded-lg transition"
                  >
                    {dupLoading ? "…" : "Copier"}
                  </button>
                  <button
                    onClick={() => { setDuplicating(null); setDupError(""); }}
                    className="px-3 py-1.5 text-xs text-slate-500 dark:text-slate-400 border border-slate-200 dark:border-slate-600 rounded-lg bg-white dark:bg-slate-800 hover:text-slate-700 transition"
                  >
                    Annuler
                  </button>
                </div>
                {dupError && <p className="mt-1.5 text-xs text-red-500">{dupError}</p>}
              </div>
            )}

            <div className="bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden divide-y divide-slate-100 dark:divide-slate-700">
              {grouped[day].map((ev) => {
                const cfg = EVENT_CONFIG[ev.type];
                const isExpanded = expandedId === ev.id;
                const summary = getEventSummary(ev);

                const isSelected = selected.has(ev.id);

                return (
                  <div key={ev.id} className={isSelected ? "bg-indigo-50 dark:bg-indigo-950/30" : ""}>
                    <button
                      className="w-full text-left flex items-center gap-3 px-4 py-3 hover:bg-slate-50 dark:hover:bg-slate-700/50 transition"
                      onClick={() => selectMode ? toggleSelect(ev.id) : setExpandedId(isExpanded ? null : ev.id)}
                    >
                      {selectMode && (
                        <div className="flex-shrink-0">
                          {isSelected
                            ? <CheckSquare className="w-4 h-4 text-indigo-600 dark:text-indigo-400" />
                            : <Square className="w-4 h-4 text-slate-300 dark:text-slate-600" />}
                        </div>
                      )}
                      <div className={`w-8 h-8 rounded-lg ${cfg.bgClass} flex items-center justify-center flex-shrink-0`}>
                        <EventIcon name={cfg.icon} className={`w-4 h-4 ${cfg.colorClass}`} />
                      </div>
                      <div className="flex-1 min-w-0">
                        <span className="text-sm font-medium text-slate-700 dark:text-slate-200">{cfg.label}</span>
                        {summary && <span className="text-xs text-slate-400 dark:text-slate-500 ml-2">{summary}</span>}
                        {ev.notes && <p className="text-xs text-slate-400 dark:text-slate-500 truncate mt-0.5 italic">{ev.notes}</p>}
                      </div>
                      {typeof ev.metadata?.photo === "string" && ev.metadata.photo && (
                        <ImageIcon className="w-3.5 h-3.5 text-slate-400 dark:text-slate-500 flex-shrink-0" />
                      )}
                      <span className="text-xs text-slate-400 dark:text-slate-500 flex-shrink-0 font-mono">
                        {format(new Date(ev.startedAt), "HH:mm")}
                      </span>
                    </button>

                    {isExpanded && (
                      <div className="px-4 pb-4 bg-slate-50 dark:bg-slate-800/60 border-t border-slate-100 dark:border-slate-700 space-y-3 pt-3">
                        <div className="grid grid-cols-3 gap-4 text-xs">
                          <div>
                            <p className="text-slate-400 dark:text-slate-500 mb-0.5">Début</p>
                            <p className="font-mono font-medium text-slate-700 dark:text-slate-200">{format(new Date(ev.startedAt), "HH:mm")}</p>
                          </div>
                          {ev.endedAt && (
                            <div>
                              <p className="text-slate-400 dark:text-slate-500 mb-0.5">Fin</p>
                              <p className="font-mono font-medium text-slate-700 dark:text-slate-200">{format(new Date(ev.endedAt), "HH:mm")}</p>
                            </div>
                          )}
                          <div>
                            <p className="text-slate-400 dark:text-slate-500 mb-0.5">Noté par</p>
                            <p className="font-medium text-slate-700 dark:text-slate-200">{ev.user.name}</p>
                          </div>
                        </div>

                        {editingNotes?.id === ev.id ? (
                          <div className="space-y-2">
                            <textarea
                              value={editingNotes.notes}
                              onChange={(e) => setEditingNotes({ id: ev.id, notes: e.target.value })}
                              rows={2}
                              className="w-full px-3 py-2 rounded-lg border border-slate-200 dark:border-slate-600 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-400 resize-none bg-white dark:bg-slate-700 dark:text-slate-100"
                              placeholder="Observations..."
                              autoFocus
                            />
                            <div className="flex gap-2">
                              <button onClick={() => saveNotes(ev.id, editingNotes.notes)}
                                className="flex-1 py-1.5 bg-indigo-600 text-white text-xs rounded-lg font-medium">
                                Sauvegarder
                              </button>
                              <button onClick={() => setEditingNotes(null)}
                                className="py-1.5 px-3 border border-slate-200 dark:border-slate-600 text-xs rounded-lg text-slate-600 dark:text-slate-300 bg-white dark:bg-slate-700">
                                Annuler
                              </button>
                            </div>
                          </div>
                        ) : (
                          <button
                            onClick={() => setEditingNotes({ id: ev.id, notes: ev.notes ?? "" })}
                            className="flex items-center gap-2 text-xs text-slate-500 dark:text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition"
                          >
                            <StickyNote className="w-3.5 h-3.5" />
                            <span>{ev.notes ? ev.notes : "Ajouter une note..."}</span>
                            {savedNoteId === ev.id && <span className="text-xs text-emerald-500 ml-2">✓</span>}
                          </button>
                        )}

                        {typeof ev.metadata?.photo === "string" && (
                          <a href={ev.metadata.photo} target="_blank" rel="noopener noreferrer" className="block relative w-full h-48 rounded-xl overflow-hidden border border-slate-200 dark:border-slate-600">
                            <Image src={ev.metadata.photo} alt="Photo" fill className="object-cover" unoptimized />
                          </a>
                        )}

                        <div className="flex items-center gap-3">
                          <button
                            onClick={() => { setEditingEvent(ev); setExpandedId(null); }}
                            className="flex items-center gap-1.5 text-xs text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition"
                          >
                            <Pencil className="w-3.5 h-3.5" />
                            Modifier
                          </button>
                          <button
                            onClick={() => { if (confirm("Supprimer cet événement ?")) deleteEvent(ev.id); }}
                            className="flex items-center gap-1.5 text-xs text-red-400 hover:text-red-600 transition"
                          >
                            <Trash2 className="w-3.5 h-3.5" />
                            Supprimer
                          </button>
                        </div>
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
          </div>
        ))}

        {hasMore && (
          <button
            onClick={() => setPage((p) => p + 1)}
            className="w-full py-2.5 border border-slate-200 dark:border-slate-700 rounded-xl text-sm text-slate-600 dark:text-slate-300 hover:border-indigo-300 dark:hover:border-indigo-500 hover:text-indigo-600 dark:hover:text-indigo-400 bg-white dark:bg-slate-800 transition"
          >
            Charger plus · {total - (page + 1) * PAGE_SIZE} restants
          </button>
        )}

        {!isLoading && events.length === 0 && (
          <div className="text-center py-16 text-slate-400 dark:text-slate-500">
            <p className="text-sm">Aucun événement enregistré</p>
          </div>
        )}
      </div>

      {editingEvent && (
        <EventModal
          type={editingEvent.type}
          babyId={selectedBaby!.id}
          initialEvent={editingEvent}
          onClose={() => setEditingEvent(null)}
          onSaved={() => {
            qc.invalidateQueries({ queryKey: ["events"] });
            setEditingEvent(null);
          }}
        />
      )}
    </div>
  );
}
