import { useEffect, useRef, useState } from "react";
import { useParams, useLocation } from "wouter";
import { trpc } from "@/lib/trpc";
import { Button } from "@/components/ui/button";
import { io, Socket } from "socket.io-client";
import {
  ChevronLeft, Play, UserX, Trash2, QrCode, Monitor,
  Users, Clock, Printer, RefreshCw, Loader2, Power, PowerOff
} from "lucide-react";
import { toast } from "sonner";

type EntryStatus = "waiting" | "called" | "in_consultation" | "done" | "absent" | "canceled";

interface QueueEntry {
  id: number;
  ticketNumber: number;
  patientName: string | null;
  status: EntryStatus;
  position: number;
  joinedAt: Date;
  estimatedWaitMinutes: number | null;
  isPrinted: boolean;
}

export default function QueueManagement() {
  const params = useParams<{ clinicId: string }>();
  const [, navigate] = useLocation();
  const clinicId = parseInt(params.clinicId || "0");
  const socketRef = useRef<Socket | null>(null);
  const [liveQueue, setLiveQueue] = useState<QueueEntry[] | null>(null);

  const clinicQuery = trpc.clinic.get.useQuery({ id: clinicId }, { enabled: !!clinicId });
  const queueQuery = trpc.queue.getQueue.useQuery({ clinicId }, { enabled: !!clinicId, refetchInterval: 10000 });
  const qrQuery = trpc.clinic.getQrCode.useQuery({ id: clinicId }, { enabled: !!clinicId });

  const callNext = trpc.queue.callNext.useMutation({
    onSuccess: (data) => { toast.success(`Ticket #${data.calledTicket} appelé !`); queueQuery.refetch(); },
    onError: (e) => toast.error(e.message),
  });
  const markAbsent = trpc.queue.markAbsent.useMutation({
    onSuccess: () => { toast.success("Patient marqué absent"); queueQuery.refetch(); },
    onError: (e) => toast.error(e.message),
  });
  const removeEntry = trpc.queue.remove.useMutation({
    onSuccess: () => { toast.success("Patient retiré de la file"); queueQuery.refetch(); },
    onError: (e) => toast.error(e.message),
  });
  const toggleQueue = trpc.clinic.toggleQueue.useMutation({
    onSuccess: () => { toast.success("Statut de la file mis à jour"); clinicQuery.refetch(); },
    onError: (e) => toast.error(e.message),
  });
  const resetQueue = trpc.queue.reset.useMutation({
    onSuccess: () => { toast.success("File réinitialisée"); queueQuery.refetch(); clinicQuery.refetch(); },
    onError: (e) => toast.error(e.message),
  });
  const printTicket = trpc.queue.printTicket.useMutation({
    onSuccess: (data) => {
      toast.success(`Ticket #${data.ticketNumber} créé`);
      window.open(data.printUrl, "_blank");
      queueQuery.refetch();
    },
    onError: (e) => toast.error(e.message),
  });

  // WebSocket for live updates
  useEffect(() => {
    if (!clinicId) return undefined;
    const socket = io("/", { path: "/api/socket.io", transports: ["websocket", "polling"] });
    socketRef.current = socket;
    socket.emit("doctor:join", { clinicId });
    socket.on("queue:update", (data: { waiting: QueueEntry[] }) => {
      if (data.waiting) setLiveQueue(data.waiting);
    });
    return () => { socket.disconnect(); };
  }, [clinicId]);

  const queue = liveQueue ?? (queueQuery.data as QueueEntry[] | undefined) ?? [];
  const clinic = clinicQuery.data;
  const waiting = queue.filter((e) => e.status === "waiting");
  const called = queue.filter((e) => e.status === "called");

  const statusBadge = (status: EntryStatus) => {
    const map: Record<EntryStatus, string> = {
      waiting: "badge-waiting",
      called: "badge-called",
      in_consultation: "badge-called",
      done: "badge-done",
      absent: "badge-absent",
      canceled: "badge-absent",
    };
    const labels: Record<EntryStatus, string> = {
      waiting: "En attente",
      called: "Appelé",
      in_consultation: "En consultation",
      done: "Terminé",
      absent: "Absent",
      canceled: "Annulé",
    };
    return <span className={map[status]}>{labels[status]}</span>;
  };

  return (
    <div className="min-h-screen">
      <div className="absolute inset-0 pointer-events-none">
        <div className="absolute top-0 left-0 w-full h-64 bg-gradient-to-b from-primary/5 to-transparent" />
      </div>

      {/* Header */}
      <header className="relative z-10 border-b border-border/50 backdrop-blur-xl bg-background/60 sticky top-0">
        <div className="container flex items-center justify-between h-16 gap-4">
          <Button variant="ghost" size="sm" onClick={() => navigate("/dashboard")} className="text-muted-foreground flex-shrink-0">
            <ChevronLeft className="w-4 h-4 mr-1" /> Retour
          </Button>
          <div className="text-center min-w-0">
            <h1 className="font-display font-bold text-base gradient-text truncate">{clinic?.name ?? "Chargement..."}</h1>
            <p className="text-muted-foreground text-xs">{waiting.length} en attente · {called.length} appelé</p>
          </div>
          <div className="flex items-center gap-2 flex-shrink-0">
            <Button
              variant="outline" size="sm"
              onClick={() => window.open(`/display/${clinicId}`, "_blank")}
              className="border-border/60 text-muted-foreground hover:text-foreground hidden sm:flex"
            >
              <Monitor className="w-4 h-4" />
            </Button>
            <Button
              size="sm"
              onClick={() => toggleQueue.mutate({ id: clinicId, isOpen: !clinic?.isQueueOpen })}
              disabled={toggleQueue.isPending}
              className={clinic?.isQueueOpen ? "bg-destructive/20 border border-destructive/40 text-destructive hover:bg-destructive/30" : "bg-primary text-primary-foreground hover:bg-primary/90 glow-teal"}
            >
              {clinic?.isQueueOpen ? <><PowerOff className="w-4 h-4 mr-1" /> Fermer</> : <><Power className="w-4 h-4 mr-1" /> Ouvrir</>}
            </Button>
          </div>
        </div>
      </header>

      <main className="relative z-10 container py-6">
        <div className="grid lg:grid-cols-3 gap-6">
          {/* Left: Controls */}
          <div className="space-y-4">
            {/* Call next */}
            <div className="glass-card rounded-2xl p-6">
              <h2 className="font-display font-bold text-sm text-muted-foreground uppercase tracking-widest mb-4">Actions</h2>
              <Button
                onClick={() => callNext.mutate({ clinicId })}
                disabled={callNext.isPending || waiting.length === 0}
                className="w-full bg-primary text-primary-foreground hover:bg-primary/90 glow-teal h-14 text-base font-semibold mb-3"
              >
                {callNext.isPending ? <Loader2 className="w-5 h-5 animate-spin mr-2" /> : <Play className="w-5 h-5 mr-2" />}
                Appeler le suivant
              </Button>
              <Button
                onClick={() => printTicket.mutate({ clinicId })}
                disabled={printTicket.isPending || !clinic?.isQueueOpen}
                variant="outline"
                className="w-full border-border/60 text-muted-foreground hover:text-foreground mb-3"
              >
                <Printer className="w-4 h-4 mr-2" /> Imprimer un ticket
              </Button>
              <Button
                onClick={() => { if (confirm("Réinitialiser toute la file ?")) resetQueue.mutate({ clinicId }); }}
                disabled={resetQueue.isPending}
                variant="outline"
                className="w-full border-destructive/30 text-destructive hover:bg-destructive/10"
              >
                <RefreshCw className="w-4 h-4 mr-2" /> Réinitialiser la file
              </Button>
            </div>

            {/* QR Code */}
            <div className="glass-card rounded-2xl p-6">
              <h2 className="font-display font-bold text-sm text-muted-foreground uppercase tracking-widest mb-4">QR Code</h2>
              {qrQuery.data ? (
                <div className="text-center">
                  <img src={qrQuery.data.qrDataUrl} alt="QR Code" className="w-40 h-40 mx-auto rounded-xl mb-3" />
                  <p className="text-muted-foreground text-xs mb-3">
                    Expire : {qrQuery.data.expiresAt ? new Date(qrQuery.data.expiresAt).toLocaleTimeString("fr-FR") : "—"}
                  </p>
                  <div className="flex gap-2">
                    <Button variant="outline" size="sm" onClick={() => qrQuery.refetch()} className="flex-1 border-border/60 text-muted-foreground">
                      <RefreshCw className="w-3 h-3 mr-2" /> Renouveler
                    </Button>
                    <Button variant="outline" size="sm" onClick={() => navigate(`/dashboard/poster/${clinicId}`)} className="flex-1 border-border/60 text-muted-foreground">
                      <Printer className="w-3 h-3 mr-2" /> Affiche
                    </Button>
                  </div>
                </div>
              ) : (
                <div className="flex items-center justify-center py-8">
                  <Loader2 className="w-6 h-6 text-primary animate-spin" />
                </div>
              )}
            </div>

            {/* Stats */}
            <div className="glass-card rounded-2xl p-6">
              <h2 className="font-display font-bold text-sm text-muted-foreground uppercase tracking-widest mb-4">Statistiques</h2>
              <div className="space-y-3">
                {[
                  { label: "En attente", value: waiting.length, icon: Users },
                  { label: "Appelé", value: called.length, icon: Play },
                  { label: "Attente moy.", value: `~${clinic?.avgConsultationMinutes ?? 15} min`, icon: Clock },
                ].map((s) => (
                  <div key={s.label} className="flex items-center justify-between">
                    <div className="flex items-center gap-2 text-muted-foreground text-sm">
                      <s.icon className="w-4 h-4" />
                      {s.label}
                    </div>
                    <span className="font-display font-bold text-foreground">{s.value}</span>
                  </div>
                ))}
              </div>
            </div>
          </div>

          {/* Right: Queue list */}
          <div className="lg:col-span-2">
            <div className="glass-card rounded-2xl overflow-hidden">
              <div className="p-4 border-b border-border/50 flex items-center justify-between">
                <h2 className="font-display font-bold">File d'attente</h2>
                <span className="text-muted-foreground text-sm">{queue.length} patient{queue.length > 1 ? "s" : ""}</span>
              </div>

              {queueQuery.isLoading ? (
                <div className="flex items-center justify-center py-16">
                  <Loader2 className="w-6 h-6 text-primary animate-spin" />
                </div>
              ) : queue.length === 0 ? (
                <div className="text-center py-16">
                  <Users className="w-12 h-12 text-muted-foreground/30 mx-auto mb-4" />
                  <p className="text-muted-foreground">Aucun patient en file d'attente</p>
                  {!clinic?.isQueueOpen && (
                    <p className="text-muted-foreground text-sm mt-2">Ouvrez la file pour commencer à accepter des patients</p>
                  )}
                </div>
              ) : (
                <div className="divide-y divide-border/50">
                  {queue.map((entry) => (
                    <div key={entry.id} className={`flex items-center gap-4 p-4 transition-all ${entry.status === "called" ? "bg-teal-500/5" : "hover:bg-muted/20"}`}>
                      {/* Ticket number */}
                      <div className={`w-12 h-12 rounded-xl flex items-center justify-center font-display font-bold text-lg flex-shrink-0 ${entry.status === "called" ? "bg-primary/20 border border-primary/40 text-primary" : "bg-muted border border-border text-foreground"}`}>
                        {String(entry.ticketNumber).padStart(3, "0")}
                      </div>

                      {/* Info */}
                      <div className="flex-1 min-w-0">
                        <div className="flex items-center gap-2 mb-1">
                          <span className="font-medium text-sm">{entry.patientName ?? `Patient #${entry.ticketNumber}`}</span>
                          {entry.isPrinted && <span className="text-xs text-muted-foreground bg-muted rounded px-1.5 py-0.5">Ticket imprimé</span>}
                        </div>
                        <div className="flex items-center gap-3 text-xs text-muted-foreground">
                          <span>Pos. {entry.position}</span>
                          <span>·</span>
                          <span>~{entry.estimatedWaitMinutes ?? "?"} min</span>
                          <span>·</span>
                          <span>{new Date(entry.joinedAt).toLocaleTimeString("fr-FR", { hour: "2-digit", minute: "2-digit" })}</span>
                        </div>
                      </div>

                      {/* Status */}
                      <div className="flex-shrink-0">
                        {statusBadge(entry.status)}
                      </div>

                      {/* Actions */}
                      {(entry.status === "waiting" || entry.status === "called") && (
                        <div className="flex items-center gap-1 flex-shrink-0">
                          <Button
                            variant="ghost" size="sm"
                            onClick={() => markAbsent.mutate({ entryId: entry.id, clinicId })}
                            disabled={markAbsent.isPending}
                            className="text-amber-400 hover:text-amber-300 hover:bg-amber-500/10 w-8 h-8 p-0"
                            title="Marquer absent"
                          >
                            <UserX className="w-4 h-4" />
                          </Button>
                          <Button
                            variant="ghost" size="sm"
                            onClick={() => removeEntry.mutate({ entryId: entry.id, clinicId })}
                            disabled={removeEntry.isPending}
                            className="text-destructive hover:text-destructive hover:bg-destructive/10 w-8 h-8 p-0"
                            title="Retirer de la file"
                          >
                            <Trash2 className="w-4 h-4" />
                          </Button>
                        </div>
                      )}
                    </div>
                  ))}
                </div>
              )}
            </div>
          </div>
        </div>
      </main>
    </div>
  );
}
