import { useAuth } from "@/_core/hooks/useAuth";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { buildRoutePrefetchHandlers } from "@/lib/routePrefetch";
import { trpc } from "@/lib/trpc";
import { useViewportFlags } from "@/hooks/useMobile";
import { cn } from "@/lib/utils";
import { associationCommuneOptions, getAssociationCommuneLabel, type AssociationCommuneFilter } from "@shared/associationCommunes";
import { associationThematicOptions, getAssociationThematicLabel, getAssociationThematicLabels, type AssociationThematic } from "@shared/associationThematics";
import { ArrowLeft, ArrowUpRight, Building2, Copy, Facebook, Globe, Instagram, Loader2, Mail, MapPinned, Search, Users } from "lucide-react";
import { useState } from "react";
import { Link, useLocation } from "wouter";
import { toast } from "sonner";

function getPublicGeoStatus(entry: {
  latitude?: number | null;
  longitude?: number | null;
  geoSource?: string | null;
  geoPrecision?: string | null;
}) {
  const hasCoordinates = typeof entry.latitude === "number" && typeof entry.longitude === "number";

  if (!hasCoordinates || !entry.geoSource) {
    return {
      label: "Non localisée",
      className: "bg-slate-50 text-slate-700 border-slate-200",
    };
  }

  if (entry.geoSource === "manual") {
    return {
      label: "Position manuelle",
      className: "bg-emerald-50 text-emerald-700 border-emerald-200",
    };
  }

  if (entry.geoPrecision === "commune_center" || entry.geoSource === "commune_center") {
    return {
      label: "Centre de commune",
      className: "bg-amber-50 text-amber-800 border-amber-200",
    };
  }

  return {
    label: "Adresse exacte",
    className: "bg-blue-50 text-blue-700 border-blue-200",
  };
}

export default function AssociationDirectoryPortal() {
  const { user } = useAuth();
  const { isMobile, isTablet } = useViewportFlags();
  const [location] = useLocation();
  const utils = trpc.useUtils();
  const [search, setSearch] = useState("");
  const [communeFilter, setCommuneFilter] = useState<AssociationCommuneFilter>("all");
  const [statusFilter, setStatusFilter] = useState<"all" | "registered" | "unregistered">("all");
  const [thematiqueFilter, setThematiqueFilter] = useState<AssociationThematic | "all">("all");

  const { data, isLoading } = trpc.associationDirectory.listPortal.useQuery({
    search: search || undefined,
    commune: communeFilter,
    thematique: thematiqueFilter,
    registrationStatus: statusFilter,
    limit: 100,
  });

  const sendInvitationMutation = trpc.associationInvitation.send.useMutation({
    onSuccess: (result) => {
      toast.success(
        result.emailSent
          ? "Invitation envoyée à l'adresse officielle."
          : "Invitation créée, mais l'email n'a pas pu être envoyé. Utilise le lien sécurisé."
      );
      void utils.associationDirectory.listPortal.invalidate();
    },
    onError: (error) => {
      toast.error(error.message || "Impossible d'envoyer l'invitation.");
    },
  });

  const secureLinkMutation = trpc.associationInvitation.getSecureLink.useMutation({
    onError: (error) => {
      toast.error(error.message || "Impossible de récupérer le lien sécurisé.");
    },
  });

  const isAdmin = user?.role === "admin" || user?.role === "super_admin";
  const backHref = location.startsWith("/dashboard") || user ? "/dashboard" : "/";
  const publicNavItems = [
    { href: "/associations", label: "Annuaire", active: location === "/associations" || location.startsWith("/dashboard/associations") },
    { href: "/associations/carte", label: "Carte publique", active: location.startsWith("/associations/carte") },
  ];

  const formatDate = (date: Date | string | null | undefined) => {
    if (!date) return "-";
    return new Date(date).toLocaleDateString("fr-FR", {
      day: "2-digit",
      month: "2-digit",
      year: "numeric",
    });
  };

  const getInvitationStatusLabel = (entry: NonNullable<typeof data>["data"][number]) => {
    if (entry.registered) return "Acceptée";
    switch (entry.invitationStatus?.status) {
      case "sent":
        return "Invitation envoyée";
      case "expired":
        return "Expirée";
      case "accepted":
        return "Acceptée";
      default:
        return "Jamais invitée";
    }
  };

  const copySecureInvitationLink = async (directoryEntryId: number) => {
    try {
      const result = await secureLinkMutation.mutateAsync({ directoryEntryId });
      const link = result.invitationLink;
      await navigator.clipboard.writeText(link);
      toast.success("Lien sécurisé copié. Tu peux maintenant l'envoyer à l'association.");
      void utils.associationDirectory.listPortal.invalidate();
    } catch {
      toast.error("Impossible de copier le lien automatiquement.");
    }
  };

  return (
    <div className="portal-immersive-page min-h-screen">
      <header className="border-b border-border bg-white sticky top-0 z-10">
        <div className="container py-3 sm:py-4">
          <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
            <div className="flex items-center gap-4">
              <Link href={backHref} {...buildRoutePrefetchHandlers(backHref)}>
                <Button variant="ghost" size="icon">
                  <ArrowLeft className="h-5 w-5" />
                </Button>
              </Link>
              <div data-tour-id="directory-header">
                <h1 className="text-lg font-bold sm:text-xl">Annuaire des associations</h1>
                <p className="text-sm text-muted-foreground">
                  Consulte le bordereau public des associations des Savanes, même avant leur inscription sur le portail.
                </p>
              </div>
            </div>
            <div className="flex items-center gap-3 self-start sm:self-auto">
              <Badge variant="outline" className="bg-primary/5 text-primary border-primary/20">
                {data?.total || 0} visible(s)
              </Badge>
              <Link href="/associations/carte" {...buildRoutePrefetchHandlers("/associations/carte")}>
                <Button variant="outline" size="sm" className="min-h-10">
                  <MapPinned className="mr-2 h-4 w-4" />
                  Carte publique
                </Button>
              </Link>
            </div>
          </div>
        </div>
      </header>

      <main className="container space-y-5 py-5 sm:space-y-6 sm:py-8">
        <div className="flex gap-2 overflow-x-auto pb-1 sm:hidden">
          {publicNavItems.map((item) => (
            <Link key={item.href} href={item.href} {...buildRoutePrefetchHandlers(item.href)}>
              <Button
                type="button"
                variant={item.active ? "default" : "outline"}
                size="sm"
                className="min-h-10 shrink-0 rounded-full px-4"
              >
                {item.label}
              </Button>
            </Link>
          ))}
        </div>

        <section className="rounded-3xl border border-slate-200 bg-white shadow-[0_18px_44px_rgba(15,23,42,0.06)]">
          <div className="grid gap-0 xl:grid-cols-[1.2fr_0.8fr]">
            <div className="space-y-5 p-5 lg:p-8">
              <div className="space-y-3">
                <Badge variant="outline" className="border-emerald-200 bg-emerald-50 text-emerald-800">
                  Annuaire public
                </Badge>
                <div className="space-y-2">
                  <h2 className="text-xl font-semibold tracking-tight sm:text-2xl">Bordereau partagé des associations</h2>
                  <p className="max-w-3xl text-sm leading-6 text-muted-foreground">
                    Recherche par nom, commune ou thématique pour retrouver rapidement une association et ouvrir sa fiche publique.
                  </p>
                </div>
              </div>

              <div className="grid gap-3 sm:grid-cols-3">
                <div className="rounded-2xl border border-slate-200 bg-slate-50 px-4 py-4">
                  <p className="text-xs uppercase tracking-wide text-muted-foreground">Associations visibles</p>
                  <p className="mt-2 text-3xl font-semibold text-slate-900">{data?.total || 0}</p>
                </div>
                <div className="rounded-2xl border border-slate-200 bg-slate-50 px-4 py-4">
                  <p className="text-xs uppercase tracking-wide text-muted-foreground">Commune active</p>
                  <p className="mt-2 text-base font-semibold text-slate-900">{getAssociationCommuneLabel(communeFilter)}</p>
                </div>
                <div className="rounded-2xl border border-slate-200 bg-slate-50 px-4 py-4">
                  <p className="text-xs uppercase tracking-wide text-muted-foreground">Filtre portail</p>
                  <p className="mt-2 text-sm font-medium text-slate-700">
                    {statusFilter === "registered"
                      ? "Associations déjà inscrites"
                      : statusFilter === "unregistered"
                        ? "Associations à activer"
                        : "Tous les statuts"}
                  </p>
                </div>
              </div>
            </div>

            <div className="border-t border-slate-200 bg-slate-50/90 p-5 lg:p-8 xl:border-l xl:border-t-0">
              <div className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
                <p className="text-sm font-semibold text-slate-900">Repères de lecture</p>
                <div className="mt-4 space-y-3 text-sm text-slate-600">
                  <div className="flex items-start gap-3">
                    <span className="mt-1 h-2.5 w-2.5 rounded-full bg-emerald-500" />
                    <p>Les cartes mettent en avant la localisation, l’état d’activation et les identifiants utiles.</p>
                  </div>
                  <div className="flex items-start gap-3">
                    <span className="mt-1 h-2.5 w-2.5 rounded-full bg-blue-500" />
                    <p>Les fiches publiques et la carte restent accessibles sans casser le parcours de consultation.</p>
                  </div>
                  <div className="flex items-start gap-3">
                    <span className="mt-1 h-2.5 w-2.5 rounded-full bg-amber-500" />
                    <p>Les associations non encore inscrites peuvent être invitées proprement depuis l’espace interne.</p>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </section>

        <Card className="border-slate-200 shadow-sm">
          <CardContent className="space-y-4 p-4 sm:p-6">
            <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
              <div className="relative w-full lg:w-[320px]">
                <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
                <Input
                  placeholder="Rechercher une association, un SIRET ou un RNA..."
                  value={search}
                  onChange={(e) => setSearch(e.target.value)}
                  className="min-h-11 pl-9"
                />
              </div>
              <div className="w-full lg:w-[280px]">
                <Select value={thematiqueFilter} onValueChange={(value) => setThematiqueFilter(value as AssociationThematic | "all")}>
                  <SelectTrigger className="min-h-11">
                    <SelectValue placeholder="Filtrer par catégorie" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="all">Toutes les thématiques</SelectItem>
                    {associationThematicOptions.map((option) => (
                      <SelectItem key={option.value} value={option.value}>
                        {option.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div className="flex gap-2 overflow-x-auto pb-1 lg:flex-wrap lg:overflow-visible">
                {[
                  { value: "all", label: "Toutes" },
                  { value: "registered", label: "Inscrites" },
                  { value: "unregistered", label: "Pas encore inscrites" },
                ].map((option) => (
                  <Button
                    key={option.value}
                    size="sm"
                    type="button"
                    variant={statusFilter === option.value ? "default" : "outline"}
                    className="min-h-10 shrink-0 rounded-full"
                    onClick={() => setStatusFilter(option.value as "all" | "registered" | "unregistered")}
                  >
                    {option.label}
                  </Button>
                ))}
              </div>
            </div>

            <div className="flex gap-2 overflow-x-auto pb-1 sm:flex-wrap sm:overflow-visible">
              {associationCommuneOptions.map((option) => (
                <Button
                  key={option.value}
                  size="sm"
                  type="button"
                  variant={communeFilter === option.value ? "default" : "outline"}
                  className="min-h-10 shrink-0 rounded-full"
                  onClick={() => setCommuneFilter(option.value)}
                >
                  {option.label}
                </Button>
              ))}
            </div>

            <p className="text-sm text-muted-foreground">
              {data?.total || 0} association(s)
              {communeFilter !== "all" ? ` • ${getAssociationCommuneLabel(communeFilter)}` : ""}
              {thematiqueFilter !== "all" ? ` • ${getAssociationThematicLabel(thematiqueFilter)}` : ""}
              {statusFilter === "registered" ? " déjà activée(s) sur le portail" : ""}
              {statusFilter === "unregistered" ? " pas encore inscrite(s) sur le portail" : ""}
            </p>
          </CardContent>
        </Card>

        {isLoading ? (
          <div className="flex items-center justify-center py-12">
            <Loader2 className="h-8 w-8 animate-spin text-primary" />
          </div>
        ) : (
          <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
            {data?.data?.map((entry) => (
              <Card key={entry.id} className="h-full rounded-3xl border-slate-200 shadow-sm transition-all hover:-translate-y-0.5 hover:shadow-md">
                {(() => {
                  const geoStatus = getPublicGeoStatus(entry);

                  return (
                <CardHeader className="space-y-4">
                  <div className="flex items-start justify-between gap-3">
                    <div className="flex h-12 w-12 items-center justify-center rounded-2xl bg-primary/10 text-primary">
                      <Building2 className="h-5 w-5" />
                    </div>
                    <div className="flex flex-col items-end gap-2">
                      <Badge
                        variant="outline"
                        className={entry.registered ? "bg-green-50 text-green-700 border-green-200" : "bg-blue-50 text-blue-700 border-blue-200"}
                      >
                        {entry.registered ? "Inscrite" : "À activer"}
                      </Badge>
                      <Badge variant="outline" className={geoStatus.className}>
                        {geoStatus.label}
                      </Badge>
                    </div>
                  </div>
                  <div>
                    <CardTitle className="text-lg leading-6">{entry.nomAssociation}</CardTitle>
                    <CardDescription className="mt-1">
                      {entry.ville || "Commune non renseignée"}
                    </CardDescription>
                  </div>
                </CardHeader>
                  );
                })()}
                <CardContent className={cn("space-y-3 text-sm text-muted-foreground", isMobile && "pt-0")}>
                  {(entry.siret || entry.rna) ? (
                    <div className="flex flex-wrap gap-2 pb-1">
                      {entry.siret ? (
                        <span className="rounded-full bg-muted px-2 py-1 text-xs">SIRET : {entry.siret}</span>
                      ) : null}
                      {entry.rna ? (
                        <span className="rounded-full bg-muted px-2 py-1 text-xs">RNA : {entry.rna}</span>
                      ) : null}
                    </div>
                  ) : null}
                  <div className="rounded-2xl border border-slate-200 bg-slate-50 px-3 py-2.5">
                    <p className="text-xs uppercase tracking-wide text-muted-foreground">État d’invitation</p>
                    <p className="mt-2 font-medium text-foreground">{getInvitationStatusLabel(entry)}</p>
                    {entry.invitationStatus?.sentAt ? (
                      <p className="mt-1 text-xs">Envoyée le {formatDate(entry.invitationStatus.sentAt)}</p>
                    ) : null}
                    {entry.invitationStatus?.expiresAt ? (
                      <p className="mt-1 text-xs">Expire le {formatDate(entry.invitationStatus.expiresAt)}</p>
                    ) : null}
                    {!entry.registered && entry.invitationStatus?.status === "sent" && !entry.invitationStatus.emailSent ? (
                      <p className="mt-1 text-xs text-amber-700">Email non envoyé automatiquement, lien sécurisé disponible.</p>
                    ) : null}
                  </div>
                  {entry.thematiques?.length ? (
                    <div className="flex flex-wrap gap-2">
                      {getAssociationThematicLabels(entry.thematiques).map((label) => (
                        <span key={label} className="rounded-full bg-primary/10 px-2 py-1 text-xs text-primary">{label}</span>
                      ))}
                    </div>
                  ) : null}
                  {entry.adresse || entry.codePostal || entry.ville ? (
                    <p>
                      {[entry.adresse, [entry.codePostal, entry.ville].filter(Boolean).join(" ")].filter(Boolean).join(", ")}
                    </p>
                  ) : null}
                  {entry.emailOfficiel ? <p>{entry.emailOfficiel}</p> : null}
                  {entry.siteWeb ? (
                    <a
                      href={entry.siteWeb}
                      target="_blank"
                      rel="noreferrer"
                      className="inline-flex items-center gap-1 text-primary hover:underline"
                    >
                      <Globe className="h-3.5 w-3.5" />
                      Site web
                    </a>
                  ) : null}
                  <div className="space-y-1 rounded-2xl border border-slate-200 bg-white px-3 py-2.5">
                    <p>Présente dans le bordereau depuis le {formatDate(entry.importedAt)}</p>
                    <p>
                      {entry.registered
                        ? `Compte activé le ${formatDate(entry.registeredAt)}`
                        : "Cette association n'a pas encore créé son espace portail."}
                    </p>
                  </div>
                  {(entry.facebookUrl || entry.instagramUrl) ? (
                    <div className="flex flex-wrap items-center gap-2 pt-1">
                      <span className="text-xs uppercase tracking-wide text-muted-foreground">Réseaux</span>
                      {entry.facebookUrl ? (
                        <a
                          href={entry.facebookUrl}
                          target="_blank"
                          rel="noreferrer"
                          className="inline-flex items-center gap-1 rounded-full border px-2 py-1 text-xs text-foreground hover:bg-muted/50"
                        >
                          <Facebook className="h-3.5 w-3.5 text-primary" />
                          Facebook
                        </a>
                      ) : null}
                      {entry.instagramUrl ? (
                        <a
                          href={entry.instagramUrl}
                          target="_blank"
                          rel="noreferrer"
                          className="inline-flex items-center gap-1 rounded-full border px-2 py-1 text-xs text-foreground hover:bg-muted/50"
                        >
                          <Instagram className="h-3.5 w-3.5 text-primary" />
                          Instagram
                        </a>
                      ) : null}
                    </div>
                  ) : null}
                  {!entry.registered && isAdmin ? (
                    <div className="grid gap-2 pt-2">
                      <Button
                        type="button"
                        className="w-full"
                        disabled={!entry.emailOfficiel || sendInvitationMutation.isPending}
                        onClick={() => sendInvitationMutation.mutate({ directoryEntryId: entry.id })}
                      >
                        <Mail className="mr-2 h-4 w-4" />
                        {entry.emailOfficiel ? "Inviter par email" : "Email officiel requis"}
                      </Button>
                      <Button
                        type="button"
                        variant="outline"
                        className="w-full"
                        disabled={!entry.emailOfficiel || secureLinkMutation.isPending}
                        onClick={() => copySecureInvitationLink(entry.id)}
                      >
                        <Copy className="mr-2 h-4 w-4" />
                        {entry.emailOfficiel ? "Copier le lien sécurisé" : "Email officiel requis"}
                      </Button>
                    </div>
                  ) : null}
                    <div className="pt-2">
                    <Link href={`/associations/${entry.id}`} {...buildRoutePrefetchHandlers(`/associations/${entry.id}`)}>
                      <Button type="button" variant="outline" className="min-h-11 w-full">
                        <ArrowUpRight className="mr-2 h-4 w-4" />
                        Voir la fiche complète
                      </Button>
                    </Link>
                  </div>
                </CardContent>
              </Card>
            ))}
            {(!data?.data || data.data.length === 0) && (
              <Card className="md:col-span-2 xl:col-span-3 rounded-3xl border-slate-200 shadow-sm">
                <CardContent className="py-12 text-center text-muted-foreground">
                  <Users className="h-12 w-12 mx-auto mb-4 opacity-50" />
                  <p>Aucune association ne correspond aux filtres actuels.</p>
                </CardContent>
              </Card>
            )}
          </div>
        )}
      </main>
    </div>
  );
}
