"use client";

import { useState, useMemo, useCallback, useRef, useEffect, Fragment } from "react";
import { useQuery, keepPreviousData } from "@tanstack/react-query";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import {
  ChevronLeft,
  ChevronRight,
  ChevronDown,
  Search,
  MessageSquare,
  X,
  User,
  Bot,
  Loader2,
} from "lucide-react";
import { formatDate } from "@/lib/utils";
import {
  LibreChatConversation,
  LibreChatUser,
  LibreChatMessage,
} from "@/lib/types";

// Hook debounce personnalisé
function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState<T>(value);

  useEffect(() => {
    const timer = setTimeout(() => setDebouncedValue(value), delay);
    return () => clearTimeout(timer);
  }, [value, delay]);

  return debouncedValue;
}

// Types pour les messages étendus
interface ExtendedMessage extends LibreChatMessage {
  content?: Array<{ type: string; text: string }> | string;
  parts?: Array<string | { text: string }>;
  [key: string]: unknown;
}

// Fetcher générique
async function fetchCollection<T>(
  collection: string,
  params: Record<string, string | number>
): Promise<{ data: T[]; total: number; totalPages: number }> {
  const searchParams = new URLSearchParams();
  Object.entries(params).forEach(([key, value]) => {
    if (value !== undefined && value !== "") {
      searchParams.set(key, String(value));
    }
  });

  const response = await fetch(`/api/collections/${collection}?${searchParams}`);
  if (!response.ok) throw new Error(`Erreur lors du chargement de ${collection}`);
  return response.json();
}

export function ConversationsTable() {
  const [page, setPage] = useState(1);
  const [searchInput, setSearchInput] = useState("");
  const [selectedConversationId, setSelectedConversationId] = useState<string | null>(null);
  const searchInputRef = useRef<HTMLInputElement>(null);

  const limit = 20;
  const debouncedSearch = useDebounce(searchInput, 250);

  // Reset page quand la recherche change
  useEffect(() => {
    setPage(1);
  }, [debouncedSearch]);

  // Query conversations avec TanStack Query
  const {
    data: conversationsData,
    isLoading: conversationsLoading,
    isFetching: conversationsFetching,
  } = useQuery({
    queryKey: ["conversations", page, limit, debouncedSearch],
    queryFn: () =>
      fetchCollection<LibreChatConversation>("conversations", {
        page,
        limit,
        search: debouncedSearch,
      }),
    placeholderData: keepPreviousData,
    staleTime: 30000, // 30 secondes
  });

  // Query users (cache long car ça change rarement)
  const { data: usersData } = useQuery({
    queryKey: ["users", "all"],
    queryFn: () => fetchCollection<LibreChatUser>("users", { limit: 1000 }),
    staleTime: 1000 * 60 * 5, // 5 minutes
  });

  // Query messages de la conversation sélectionnée
  const { data: messagesData, isLoading: messagesLoading } = useQuery({
    queryKey: ["messages", selectedConversationId],
    queryFn: () =>
      fetchCollection<LibreChatMessage>("messages", {
        limit: 500,
        filter: JSON.stringify({ conversationId: selectedConversationId }),
      }),
    enabled: !!selectedConversationId,
    staleTime: 30000,
  });

  const conversations = conversationsData?.data ?? [];
  const total = conversationsData?.total ?? 0;
  const totalPages = conversationsData?.totalPages ?? 0;
  const users = usersData?.data ?? [];
  const messages = messagesData?.data ?? [];

  // Map des users pour lookup rapide
  const userMap = useMemo(() => new Map(users.map((u) => [u._id, u])), [users]);

  const getUserInfo = useCallback(
    (userId: string) => {
      const user = userMap.get(userId);
      return {
        name: user?.name || user?.username || `User ${userId.slice(-6)}`,
        email: user?.email || null,
      };
    },
    [userMap]
  );

  // Extraction du contenu des messages
  const getMessageContent = useCallback((message: LibreChatMessage): string => {
    const msg = message as ExtendedMessage;

    if (msg.content && Array.isArray(msg.content)) {
      for (const item of msg.content) {
        if (item?.text) return item.text.trim();
      }
    }
    if (message.text?.trim()) return message.text.trim();
    if (typeof msg.content === "string" && msg.content.trim()) return msg.content.trim();
    if (msg.parts?.[0]) {
      const part = msg.parts[0];
      if (typeof part === "string") return part.trim();
      if (part?.text) return part.text.trim();
    }
    return "Contenu non disponible";
  }, []);

  const clearSearch = () => {
    setSearchInput("");
    searchInputRef.current?.focus();
  };

  const isSearching = searchInput !== debouncedSearch || conversationsFetching;

  return (
    <div className="space-y-4">
      <Card>
        <CardHeader className="pb-4">
          <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
            <CardTitle className="flex items-center gap-2">
              <MessageSquare className="h-5 w-5" />
              Conversations
              <Badge variant="secondary" className="ml-2">
                {total}
              </Badge>
              {conversationsFetching && !conversationsLoading && (
                <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
              )}
            </CardTitle>

            {/* Barre de recherche */}
            <div className="relative w-full sm:w-96">
              <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
              <Input
                ref={searchInputRef}
                placeholder="Rechercher par nom ou email..."
                value={searchInput}
                onChange={(e) => setSearchInput(e.target.value)}
                className="pl-10 pr-10"
              />
              <div className="absolute right-3 top-1/2 -translate-y-1/2">
                {isSearching ? (
                  <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
                ) : searchInput ? (
                  <button
                    onClick={clearSearch}
                    className="text-muted-foreground hover:text-foreground transition-colors"
                    type="button"
                  >
                    <X className="h-4 w-4" />
                  </button>
                ) : null}
              </div>
            </div>
          </div>

          {debouncedSearch && (
            <p className="text-sm text-muted-foreground mt-2">
              {total} résultat{total > 1 ? "s" : ""} pour &quot;{debouncedSearch}&quot;
            </p>
          )}
        </CardHeader>

        <CardContent>
          {conversationsLoading ? (
            <div className="space-y-3">
              {Array.from({ length: 5 }).map((_, i) => (
                <div key={i} className="h-14 bg-muted animate-pulse rounded-lg" />
              ))}
            </div>
          ) : conversations.length === 0 ? (
            <div className="text-center py-12 text-muted-foreground">
              {debouncedSearch ? (
                <>
                  <Search className="h-12 w-12 mx-auto mb-4 opacity-20" />
                  <p>Aucun résultat pour &quot;{debouncedSearch}&quot;</p>
                  <Button variant="link" onClick={clearSearch} className="mt-2">
                    Effacer la recherche
                  </Button>
                </>
              ) : (
                <p>Aucune conversation</p>
              )}
            </div>
          ) : (
            <>
              <div className="rounded-md border">
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead className="w-52">Utilisateur</TableHead>
                      <TableHead>Titre</TableHead>
                      <TableHead className="w-24">Endpoint</TableHead>
                      <TableHead className="w-20 text-center">Msgs</TableHead>
                      <TableHead className="w-24">Statut</TableHead>
                      <TableHead className="w-28">Date</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {conversations.map((conv) => {
                      const userInfo = getUserInfo(String(conv.user));
                      const msgCount = conv.messages?.length || 0;
                      const isSelected = selectedConversationId === conv.conversationId;

                      return (
                        <Fragment key={conv._id}>
                          <TableRow
                            className={`cursor-pointer hover:bg-muted/50 transition-colors ${isSelected ? "bg-muted/50" : ""}`}
                            onClick={() =>
                              setSelectedConversationId(
                                isSelected ? null : conv.conversationId
                              )
                            }
                          >
                            <TableCell>
                              <div className="flex items-center gap-2">
                                <ChevronDown
                                  className={`h-4 w-4 text-muted-foreground transition-transform ${
                                    isSelected ? "rotate-0" : "-rotate-90"
                                  }`}
                                />
                                <div className="flex flex-col">
                                  <span className="font-medium truncate max-w-[180px]">
                                    {userInfo.name}
                                  </span>
                                  {userInfo.email && (
                                    <span className="text-xs text-muted-foreground truncate max-w-[180px]">
                                      {userInfo.email}
                                    </span>
                                  )}
                                </div>
                              </div>
                            </TableCell>
                            <TableCell>
                              <span className="truncate block max-w-xs" title={String(conv.title)}>
                                {String(conv.title) || "Sans titre"}
                              </span>
                            </TableCell>
                            <TableCell>
                              <Badge variant="outline" className="text-xs font-mono">
                                {String(conv.endpoint).slice(0, 10)}
                              </Badge>
                            </TableCell>
                            <TableCell className="text-center">
                              <Badge variant="secondary" className="text-xs">
                                {msgCount}
                              </Badge>
                            </TableCell>
                            <TableCell>
                              <Badge
                                variant={conv.isArchived ? "outline" : "default"}
                                className="text-xs"
                              >
                                {conv.isArchived ? "Archivée" : "Active"}
                              </Badge>
                            </TableCell>
                            <TableCell>
                              <span className="text-xs text-muted-foreground">
                                {formatDate(conv.updatedAt)}
                              </span>
                            </TableCell>
                          </TableRow>

                          {/* Messages inline sous la row */}
                          {isSelected && (
                            <TableRow key={`${conv._id}-messages`}>
                              <TableCell colSpan={6} className="p-0 border-b">
                                <div className="bg-slate-50 p-4">
                                  {messagesLoading ? (
                                    <div className="flex items-center justify-center py-8 gap-2 text-muted-foreground">
                                      <Loader2 className="h-5 w-5 animate-spin" />
                                      <span>Chargement des messages...</span>
                                    </div>
                                  ) : messages.length === 0 ? (
                                    <p className="text-center py-8 text-muted-foreground">
                                      Aucun message dans cette conversation
                                    </p>
                                  ) : (
                                    <div className="space-y-3 max-h-[400px] overflow-y-auto">
                                      {messages
                                        .sort(
                                          (a, b) =>
                                            new Date(a.createdAt).getTime() -
                                            new Date(b.createdAt).getTime()
                                        )
                                        .map((msg) => {
                                          const content = getMessageContent(msg);
                                          const isUser = msg.isCreatedByUser;

                                          return (
                                            <div
                                              key={msg._id}
                                              className={`flex gap-3 p-3 rounded-lg border-l-4 ${
                                                isUser
                                                  ? "bg-blue-50 border-l-blue-500"
                                                  : "bg-white border-l-gray-300"
                                              }`}
                                            >
                                              <div className="flex-shrink-0 mt-0.5">
                                                {isUser ? (
                                                  <User className="h-4 w-4 text-blue-600" />
                                                ) : (
                                                  <Bot className="h-4 w-4 text-gray-500" />
                                                )}
                                              </div>
                                              <div className="flex-1 min-w-0">
                                                <div className="flex items-center gap-2 mb-1 flex-wrap">
                                                  <span className="text-xs font-medium">
                                                    {isUser ? "Utilisateur" : "Assistant"}
                                                  </span>
                                                  <span className="text-xs text-muted-foreground">
                                                    {formatDate(msg.createdAt)}
                                                  </span>
                                                  {msg.tokenCount > 0 && (
                                                    <span className="text-xs text-muted-foreground">
                                                      ({msg.tokenCount} tokens)
                                                    </span>
                                                  )}
                                                </div>
                                                <div className="text-sm whitespace-pre-wrap break-words">
                                                  {content}
                                                </div>
                                              </div>
                                            </div>
                                          );
                                        })}
                                    </div>
                                  )}
                                </div>
                              </TableCell>
                            </TableRow>
                          )}
                        </Fragment>
                      );
                    })}
                  </TableBody>
                </Table>
              </div>

              {/* Pagination */}
              {totalPages > 1 && (
                <div className="flex items-center justify-between mt-4">
                  <p className="text-sm text-muted-foreground">
                    Page {page} / {totalPages}
                  </p>
                  <div className="flex gap-2">
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => setPage((p) => Math.max(1, p - 1))}
                      disabled={page === 1}
                    >
                      <ChevronLeft className="h-4 w-4" />
                      Préc.
                    </Button>
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
                      disabled={page === totalPages}
                    >
                      Suiv.
                      <ChevronRight className="h-4 w-4" />
                    </Button>
                  </div>
                </div>
              )}
            </>
          )}
        </CardContent>
      </Card>

    </div>
  );
}
