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 { trpc } from "@/lib/trpc";
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 [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 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="min-h-screen bg-muted/30">
      <header className="border-b border-border bg-white sticky top-0 z-10">
        <div className="container py-4">
          <div className="flex items-center justify-between gap-4">
            <div className="flex items-center gap-4">
              <Link href={backHref}>
                <Button variant="ghost" size="icon">
                  <ArrowLeft className="h-5 w-5" />
                </Button>
              </Link>
              <div>
                <h1 className="text-xl font-bold">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">
              <Badge variant="outline" className="bg-primary/5 text-primary border-primary/20">
                {data?.total || 0} visible(s)
              </Badge>
              <Link href="/associations/carte">
                <Button variant="outline" size="sm">
                  <MapPinned className="mr-2 h-4 w-4" />
                  Carte publique
                </Button>
              </Link>
            </div>
          </div>
        </div>
      </header>

      <main className="container py-8 space-y-6">
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Users className="h-5 w-5 text-primary" />
              Bordereau partagé
            </CardTitle>
            <CardDescription>
              Recherche par nom et filtre par commune pour retrouver rapidement une association.
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
              <div className="relative 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="pl-9"
                />
              </div>
              <div className="lg:w-[280px]">
                <Select value={thematiqueFilter} onValueChange={(value) => setThematiqueFilter(value as AssociationThematic | "all")}>
                  <SelectTrigger>
                    <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 flex-wrap gap-2">
                {[
                  { 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="rounded-full"
                    onClick={() => setStatusFilter(option.value as "all" | "registered" | "unregistered")}
                  >
                    {option.label}
                  </Button>
                ))}
              </div>
            </div>

            <div className="flex flex-wrap gap-2">
              {associationCommuneOptions.map((option) => (
                <Button
                  key={option.value}
                  size="sm"
                  type="button"
                  variant={communeFilter === option.value ? "default" : "outline"}
                  className="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">
                {(() => {
                  const geoStatus = getPublicGeoStatus(entry);

                  return (
                <CardHeader className="space-y-3">
                  <div className="flex items-start justify-between gap-3">
                    <div className="flex h-11 w-11 items-center justify-center rounded-lg 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="space-y-2 text-sm text-muted-foreground">
                  {(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}
                  {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}
                  <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>
                  {(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}
                  <div className="pt-2 space-y-1">
                    <p className="font-medium text-foreground">État d’invitation : {getInvitationStatusLabel(entry)}</p>
                    {entry.invitationStatus?.sentAt ? (
                      <p>Envoyée le {formatDate(entry.invitationStatus.sentAt)}</p>
                    ) : null}
                    {entry.invitationStatus?.expiresAt ? (
                      <p>Expire le {formatDate(entry.invitationStatus.expiresAt)}</p>
                    ) : null}
                    {!entry.registered && entry.invitationStatus?.status === "sent" && !entry.invitationStatus.emailSent ? (
                      <p className="text-amber-700">Email non envoyé automatiquement, lien sécurisé disponible.</p>
                    ) : null}
                  </div>
                  {!entry.registered && isAdmin ? (
                    <div className="grid gap-2 pt-3">
                      <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-3">
                    <Link href={`/associations/${entry.id}`}>
                      <Button type="button" variant="outline" className="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">
                <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>
  );
}
