import { useState, useMemo } from "react";
import { useLocalAuth } from "@/contexts/LocalAuthContext";
import { toast } from "sonner";
import { trpc } from "@/lib/trpc";
import { FilterBar } from "@/components/FilterBar";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
  LayoutGrid,
  List,
  Eye,
  EyeOff,
  ExternalLink,
  Calendar,
  MapPin,
  Target,
  Loader2,
  ChevronLeft,
  ChevronRight,
  AlertCircle,
  Clock,
  Trash2,
  AlertTriangle,
} from "lucide-react";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { cn } from "@/lib/utils";
import { format, isPast, differenceInDays } from "date-fns";
import { fr } from "date-fns/locale";

type AAPCategorie = "Handicap" | "PA" | "Enfance" | "Précarité" | "Sanitaire" | "Autre";
type ReadFilter = "unread" | "all" | "read";

interface AAPItem {
  id: number;
  titre: string;
  categorie: string;
  region: string | null;
  departement: string | null;
  dateCloture: Date | null;
  datePublication: Date | null;
  lien: string | null;
  importedAt: Date;
  iaRelevant: boolean | null;
  iaCategorie: string | null;
  iaClassifiedBy: "ia" | "rules" | null;
  iaReason: string | null;
  iaResume: string | null;
}

const CAT_COLORS: Record<string, string> = {
  Handicap: "bg-violet-100 text-violet-800 border-violet-200",
  PA: "bg-sky-100 text-sky-800 border-sky-200",
  Enfance: "bg-pink-100 text-pink-800 border-pink-200",
  "Précarité": "bg-orange-100 text-orange-800 border-orange-200",
  Sanitaire: "bg-teal-100 text-teal-800 border-teal-200",
  Autre: "bg-gray-100 text-gray-700 border-gray-200",
};

const CAT_ACCENT: Record<string, string> = {
  Handicap: "border-l-violet-500",
  PA: "border-l-sky-500",
  Enfance: "border-l-pink-500",
  "Précarité": "border-l-orange-500",
  Sanitaire: "border-l-teal-500",
  Autre: "border-l-gray-400",
};

const PAGE_SIZE = 24;

function formatDate(d: Date | null | undefined): string | null {
  if (!d) return null;
  try { return format(new Date(d), "d MMM yyyy", { locale: fr }); }
  catch { return null; }
}

function ClotureStatus({ date }: { date: Date | null | undefined }) {
  if (!date) return <span className="text-muted-foreground text-xs">—</span>;
  const d = new Date(date);
  const past = isPast(d);
  const daysLeft = differenceInDays(d, new Date());

  if (past) {
    return (
      <span className="inline-flex items-center gap-1 text-xs text-red-600 font-medium">
        <AlertCircle size={11} />
        Clôturé
      </span>
    );
  }
  if (daysLeft <= 7) {
    return (
      <span className="inline-flex items-center gap-1 text-xs text-amber-600 font-medium">
        <Clock size={11} />
        {daysLeft}j restants
      </span>
    );
  }
  return <span className="text-xs text-muted-foreground">{formatDate(d)}</span>;
}

export default function AAPDashboard() {
  const { user } = useLocalAuth();
  const isAdmin = user?.role === "admin";
  const utils = trpc.useUtils();

  // Marquage lu/non lu
  const [readIds, setReadIds] = useState<Set<number>>(new Set());
  const markAsReadMutation = trpc.aap.markAsRead.useMutation({
    onSuccess: (_, vars) => {
      setReadIds((prev) => { const next = new Set(prev); next.add(vars.articleId); return next; });
    },
  });
  const markAllAsReadMutation = trpc.aap.markAllAsRead.useMutation({
    onSuccess: () => { utils.aap.unreadCount.invalidate(); },
  });
  const unreadCountQuery = trpc.aap.unreadCount.useQuery();
  const unreadCount = unreadCountQuery.data?.count ?? 0;

  const purgeMutation = trpc.aap.purge.useMutation({
    onSuccess: (data) => {
      toast.success(`Purge effectuée — ${data.deleted} entrée(s) supprimée(s)`);
      utils.aap.list.invalidate();
      utils.aap.filters.invalidate();
    },
    onError: (err) => {
      toast.error(`Erreur lors de la purge : ${err.message}`);
    },
  });

  // ── État UI ─────────────────────────────────────────────────────────────────
  // Mode vignette par défaut
  const [viewMode, setViewMode] = useState<"list" | "grid">("grid");
  const [activeTab, setActiveTab] = useState<AAPCategorie | "all">("all");
  const [page, setPage] = useState(1);
  const [filterValues, setFilterValues] = useState<Record<string, string>>({});
  // Filtre Lu/Non lu — Non lu par défaut
  const [readFilter, setReadFilter] = useState<ReadFilter>("unread");
  // Ligne sélectionnée en mode liste
  const [selectedRowId, setSelectedRowId] = useState<number | null>(null);

  const filtersQuery = trpc.aap.filters.useQuery();

  const queryInput = useMemo(() => ({
    categorie: activeTab !== "all" ? activeTab : undefined,
    region: filterValues.region || undefined,
    departement: filterValues.departement || undefined,
    search: filterValues.search || undefined,
    dateFrom: filterValues.dateFrom ? new Date(filterValues.dateFrom) : undefined,
    dateTo: filterValues.dateTo ? new Date(filterValues.dateTo) : undefined,
    clotureFrom: filterValues.clotureFrom ? new Date(filterValues.clotureFrom) : undefined,
    clotureTo: filterValues.clotureTo ? new Date(filterValues.clotureTo) : undefined,
    page,
    pageSize: PAGE_SIZE,
  }), [activeTab, filterValues, page]);

  const itemsQuery = trpc.aap.list.useQuery(queryInput);

  const handleFilterChange = (key: string, value: string) => {
    setFilterValues((prev) => ({ ...prev, [key]: value }));
    setPage(1);
  };

  const handleReset = () => {
    setFilterValues({});
    setPage(1);
  };

  const allItems = (itemsQuery.data?.items ?? []) as AAPItem[];
  const total = itemsQuery.data?.total ?? 0;
  const totalPages = Math.ceil(total / PAGE_SIZE);

  // Filtrage Lu/Non lu côté client
  const items = useMemo(() => {
    if (readFilter === "unread") return allItems.filter((i) => !readIds.has(i.id));
    if (readFilter === "read") return allItems.filter((i) => readIds.has(i.id));
    return allItems;
  }, [allItems, readIds, readFilter]);

  const filterOptions = [
    { key: "region", label: "Région", options: filtersQuery.data?.regions ?? [] },
    { key: "departement", label: "Département", options: filtersQuery.data?.departements ?? [] },
    { key: "dateFrom", label: "Publié depuis", type: "date" as const },
    { key: "dateTo", label: "Publié jusqu'à", type: "date" as const },
    { key: "clotureFrom", label: "Clôture depuis", type: "date" as const },
    { key: "clotureTo", label: "Clôture jusqu'à", type: "date" as const },
  ];

  const categories: AAPCategorie[] = ["Handicap", "PA", "Enfance", "Précarité", "Sanitaire", "Autre"];

  const READ_FILTER_LABELS: Record<ReadFilter, string> = {
    unread: "Non lus",
    all: "Tous",
    read: "Lus",
  };
  const READ_FILTER_ORDER: ReadFilter[] = ["unread", "all", "read"];

  return (
    <div className="p-6 space-y-6 animate-fade-up">
      {/* En-tête */}
      <div className="flex items-start justify-between gap-4 flex-wrap">
        <div>
          <div className="flex items-center gap-2 mb-1">
            <Target size={22} className="text-primary" />
            <h1 className="text-2xl font-bold text-foreground">Appels à Projets</h1>
            {unreadCount > 0 && (
              <span className="inline-flex items-center justify-center min-w-[20px] h-5 px-1.5 rounded-full bg-primary text-primary-foreground text-[11px] font-bold">{unreadCount}</span>
            )}
          </div>
          <p className="text-muted-foreground text-sm">
            Handicap, Personnes Âgées, Enfance, Précarité, Sanitaire et Autre
          </p>
        </div>
        <div className="flex items-center gap-2 flex-wrap">
          {unreadCount > 0 && (
            <Button variant="outline" size="sm" onClick={() => markAllAsReadMutation.mutate()} disabled={markAllAsReadMutation.isPending} className="gap-2 text-muted-foreground">
              <Eye size={15} />
              Tout marquer comme lu
            </Button>
          )}
          {/* Boutons mode d'affichage */}
          <Button variant={viewMode === "list" ? "default" : "outline"} size="sm" onClick={() => setViewMode("list")} className="gap-2">
            <List size={15} />Liste
          </Button>
          <Button variant={viewMode === "grid" ? "default" : "outline"} size="sm" onClick={() => setViewMode("grid")} className="gap-2">
            <LayoutGrid size={15} />Vignettes
          </Button>
          {isAdmin && (
            <AlertDialog>
              <AlertDialogTrigger asChild>
                <Button variant="outline" size="sm" className="gap-2 border-destructive/50 text-destructive hover:bg-destructive hover:text-destructive-foreground ml-2">
                  <Trash2 size={15} />
                  Purger les données
                </Button>
              </AlertDialogTrigger>
              <AlertDialogContent>
                <AlertDialogHeader>
                  <AlertDialogTitle className="flex items-center gap-2">
                    <AlertTriangle size={20} className="text-destructive" />
                    Purger tous les appels à projets
                  </AlertDialogTitle>
                  <AlertDialogDescription asChild>
                    <div className="space-y-2">
                      <p>Cette action va <strong>supprimer définitivement</strong> tous les appels à projets.</p>
                      <p className="text-destructive font-medium">Cette opération est irréversible.</p>
                    </div>
                  </AlertDialogDescription>
                </AlertDialogHeader>
                <AlertDialogFooter>
                  <AlertDialogCancel>Annuler</AlertDialogCancel>
                  <AlertDialogAction
                    className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
                    onClick={() => purgeMutation.mutate()}
                    disabled={purgeMutation.isPending}
                  >
                    {purgeMutation.isPending ? "Purge en cours..." : "Oui, purger tous les appels à projets"}
                  </AlertDialogAction>
                </AlertDialogFooter>
              </AlertDialogContent>
            </AlertDialog>
          )}
        </div>
      </div>

      {/* Onglets catégories + bouton Lu/Non lu */}
      <div className="flex items-center justify-between gap-4 flex-wrap">
        <Tabs value={activeTab} onValueChange={(v) => { setActiveTab(v as AAPCategorie | "all"); setPage(1); }}>
          <TabsList className="bg-muted/50 flex-wrap h-auto gap-1">
            <TabsTrigger value="all">Tous</TabsTrigger>
            {categories.map((c) => (
              <TabsTrigger key={c} value={c}>{c}</TabsTrigger>
            ))}
          </TabsList>
        </Tabs>

        {/* Bouton segmenté Lu / Non lu */}
        <div className="flex items-center rounded-lg border border-border overflow-hidden shadow-sm">
          {READ_FILTER_ORDER.map((f) => (
            <button
              key={f}
              onClick={() => setReadFilter(f)}
              className={cn(
                "px-3 py-1.5 text-xs font-medium transition-colors flex items-center gap-1.5",
                readFilter === f
                  ? "bg-primary text-primary-foreground"
                  : "bg-background text-muted-foreground hover:bg-muted/50"
              )}
            >
              {f === "unread" && <EyeOff size={12} />}
              {f === "read" && <Eye size={12} />}
              {READ_FILTER_LABELS[f]}
              {f === "unread" && unreadCount > 0 && (
                <span className="ml-0.5 inline-flex items-center justify-center min-w-[16px] h-4 px-1 rounded-full bg-primary-foreground/20 text-[10px] font-bold">{unreadCount}</span>
              )}
            </button>
          ))}
        </div>
      </div>

      {/* Filtres */}
      <FilterBar
        filters={filterOptions}
        values={filterValues}
        onChange={handleFilterChange}
        onReset={handleReset}
        searchPlaceholder="Rechercher dans les titres…"
        totalCount={total}
      />

      {/* Contenu */}
      {itemsQuery.isLoading ? (
        <div className="flex items-center justify-center py-24">
          <Loader2 size={32} className="animate-spin text-primary" />
        </div>
      ) : items.length === 0 ? (
        <div className="flex flex-col items-center justify-center py-24 text-center">
          <Target size={48} className="text-muted-foreground/30 mb-4" />
          <p className="text-muted-foreground font-medium">
            {readFilter === "unread" ? "Aucun appel à projets non lu" : "Aucun appel à projets trouvé"}
          </p>
          <p className="text-muted-foreground/60 text-sm mt-1">
            {readFilter === "unread"
              ? "Tous les appels à projets ont été lus, ou modifiez le filtre Lu/Non lu"
              : "Modifiez vos filtres ou importez des données"}
          </p>
        </div>
      ) : viewMode === "list" ? (
        <AAPListView
          items={items}
          readIds={readIds}
          onMarkRead={(id) => markAsReadMutation.mutate({ articleId: id })}
          selectedRowId={selectedRowId}
          onSelectRow={setSelectedRowId}
        />
      ) : (
        <AAPGridView items={items} readIds={readIds} onMarkRead={(id) => markAsReadMutation.mutate({ articleId: id })} />
      )}

      {/* Pagination */}
      {totalPages > 1 && (
        <div className="flex items-center justify-center gap-2 pt-2">
          <Button variant="outline" size="sm" onClick={() => setPage((p) => Math.max(1, p - 1))} disabled={page === 1}>
            <ChevronLeft size={14} />
          </Button>
          <span className="text-sm text-muted-foreground px-2">Page {page} / {totalPages}</span>
          <Button variant="outline" size="sm" onClick={() => setPage((p) => Math.min(totalPages, p + 1))} disabled={page === totalPages}>
            <ChevronRight size={14} />
          </Button>
        </div>
      )}
    </div>
  );
}

// ─── Vue Liste ────────────────────────────────────────────────────────────────

function AAPListView({
  items,
  readIds,
  onMarkRead,
  selectedRowId,
  onSelectRow,
}: {
  items: AAPItem[];
  readIds: Set<number>;
  onMarkRead: (id: number) => void;
  selectedRowId: number | null;
  onSelectRow: (id: number | null) => void;
}) {
  return (
    <div className="rounded-xl border border-border overflow-hidden shadow-sm">
      <div className="overflow-x-auto">
        <table className="w-full text-sm">
          <thead>
            <tr className="bg-muted/60 border-b border-border">
              <th className="text-left px-4 py-3 font-semibold text-muted-foreground w-8">#</th>
              <th className="text-left px-4 py-3 font-semibold text-muted-foreground">Titre</th>
              <th className="text-left px-4 py-3 font-semibold text-muted-foreground w-28">Catégorie</th>
              <th className="text-left px-4 py-3 font-semibold text-muted-foreground w-36">Région</th>
              <th className="text-left px-4 py-3 font-semibold text-muted-foreground w-32">Département</th>
              <th className="text-left px-4 py-3 font-semibold text-muted-foreground w-28">Publication</th>
              <th className="text-left px-4 py-3 font-semibold text-muted-foreground w-32">Clôture</th>
              <th className="text-left px-4 py-3 font-semibold text-muted-foreground w-16">Lien</th>
            </tr>
          </thead>
          <tbody>
            {items.map((item, idx) => {
              const isSelected = selectedRowId === item.id;
              const isRead = readIds.has(item.id);
              const isEven = idx % 2 === 0;
              const catKey = item.iaCategorie || item.categorie;

              return (
                <tr
                  key={item.id}
                  onClick={() => onSelectRow(isSelected ? null : item.id)}
                  className={cn(
                    "border-b border-border/50 border-l-4 cursor-pointer transition-colors",
                    CAT_ACCENT[catKey] || "border-l-transparent",
                    isSelected
                      ? "bg-primary/10 hover:bg-primary/15"
                      : isEven
                        ? "bg-white hover:bg-primary/5"
                        : "bg-slate-50/80 hover:bg-primary/5"
                  )}
                >
                  <td className="px-4 py-3 text-muted-foreground/50 text-xs">{idx + 1}</td>
                  <td className="px-4 py-3">
                    <div className="flex items-start gap-2 max-w-sm">
                      {!isRead && (
                        <span className="mt-1.5 w-2 h-2 rounded-full bg-primary flex-shrink-0" title="Non lu" />
                      )}
                      <div>
                        <p className={cn(
                          "font-medium line-clamp-2 leading-snug",
                          isRead ? "text-muted-foreground" : "text-foreground",
                          isSelected && "text-primary font-semibold"
                        )}>
                          {item.titre}
                        </p>
                        {item.iaResume && (
                          <p className="text-xs text-muted-foreground mt-1 line-clamp-2">{item.iaResume}</p>
                        )}
                      </div>
                    </div>
                  </td>
                  <td className="px-4 py-3">
                    <Badge variant="outline" className={cn("text-xs", CAT_COLORS[catKey])}>
                      {catKey}
                    </Badge>
                  </td>
                  <td className="px-4 py-3 text-muted-foreground text-xs">{item.region || "—"}</td>
                  <td className="px-4 py-3 text-muted-foreground text-xs">{item.departement || "—"}</td>
                  <td className="px-4 py-3 text-muted-foreground text-xs whitespace-nowrap">
                    {formatDate(item.datePublication) || "—"}
                  </td>
                  <td className="px-4 py-3"><ClotureStatus date={item.dateCloture} /></td>
                  <td className="px-4 py-3" onClick={(e) => e.stopPropagation()}>
                    <div className="flex items-center gap-1.5">
                      {!isRead && (
                        <button
                          onClick={() => onMarkRead(item.id)}
                          className="inline-flex items-center justify-center w-7 h-7 rounded-md bg-blue-50 text-blue-600 hover:bg-blue-100 hover:text-blue-700 transition-colors border border-blue-200"
                          title="Marquer comme lu"
                        >
                          <Eye size={13} />
                        </button>
                      )}
                      {item.lien && (
                        <a
                          href={item.lien}
                          target="_blank"
                          rel="noopener noreferrer"
                          className="inline-flex items-center justify-center w-7 h-7 rounded-md bg-emerald-50 text-emerald-600 hover:bg-emerald-100 hover:text-emerald-700 transition-colors border border-emerald-200"
                          title="Ouvrir la source"
                        >
                          <ExternalLink size={13} />
                        </a>
                      )}
                    </div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}

// ─── Vue Vignettes ────────────────────────────────────────────────────────────

function AAPGridView({
  items,
  readIds,
  onMarkRead,
}: {
  items: AAPItem[];
  readIds: Set<number>;
  onMarkRead: (id: number) => void;
}) {
  return (
    <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
      {items.map((item) => {
        const catKey = item.iaCategorie || item.categorie;
        return (
          <Card
            key={item.id}
            className={cn(
              "group hover:shadow-md transition-all duration-200 border-border overflow-hidden border-l-4",
              CAT_ACCENT[catKey] || "",
              !readIds.has(item.id) && "ring-1 ring-primary/20"
            )}
          >
            <CardHeader className="pb-2 pt-4 px-4">
              <div className="flex items-start justify-between gap-2">
                <Badge variant="outline" className={cn("text-xs flex-shrink-0", CAT_COLORS[catKey])}>
                  {catKey}
                </Badge>
                <div className="flex items-center gap-1.5 flex-shrink-0">
                  {!readIds.has(item.id) && (
                    <button
                      onClick={() => onMarkRead(item.id)}
                      className="text-muted-foreground hover:text-primary transition-colors"
                      title="Marquer comme lu"
                    >
                      <Eye size={14} />
                    </button>
                  )}
                  {item.lien && (
                    <a
                      href={item.lien}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-muted-foreground hover:text-accent transition-colors"
                    >
                      <ExternalLink size={14} />
                    </a>
                  )}
                </div>
              </div>
              <div className="flex items-start gap-1.5 mt-2">
                {!readIds.has(item.id) && (
                  <span className="mt-1 w-2 h-2 rounded-full bg-primary flex-shrink-0" title="Non lu" />
                )}
                <h3 className={cn(
                  "font-semibold text-sm leading-snug line-clamp-3",
                  readIds.has(item.id) ? "text-muted-foreground" : "text-foreground"
                )}>
                  {item.titre}
                </h3>
              </div>
            </CardHeader>
            <CardContent className="px-4 pb-4 space-y-2">
              {item.iaResume && (
                <p className="text-xs text-muted-foreground line-clamp-3 leading-relaxed">{item.iaResume}</p>
              )}
              <div className="flex flex-wrap gap-1.5">
                {item.region && (
                  <span className="inline-flex items-center gap-1 text-xs px-1.5 py-0.5 rounded bg-violet-50 text-violet-700 border border-violet-200">
                    <MapPin size={10} />{item.region}
                  </span>
                )}
                {item.departement && (
                  <span className="inline-flex items-center gap-1 text-xs px-1.5 py-0.5 rounded bg-teal-50 text-teal-700 border border-teal-200">
                    <MapPin size={10} />{item.departement}
                  </span>
                )}
              </div>
              <div className="flex items-center justify-between pt-1 border-t border-border/50 flex-wrap gap-1">
                {item.datePublication && (
                  <span className="inline-flex items-center gap-1 text-xs px-1.5 py-0.5 rounded bg-orange-50 text-orange-700 border border-orange-200">
                    <Calendar size={10} />
                    {formatDate(item.datePublication)}
                  </span>
                )}
                <ClotureStatus date={item.dateCloture} />
              </div>
            </CardContent>
          </Card>
        );
      })}
    </div>
  );
}
