"use client";

import { useState, useEffect, useCallback } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Users } from "lucide-react";
import Link from "next/link";
import { useCollection } from "@/hooks/useCollection";
import {
  LibreChatUser,
  LibreChatConversation,
  LibreChatBalance,
  LibreChatMessage,
} from "@/lib/types";

interface DashboardUser {
  userId: string;
  userName: string;
  conversations: number;
  tokens: number;
  credits: number;
}

// Interfaces pour les collections tokens et toolcalls
interface TokenDocument {
  _id: string;
  user?: string;
  userId?: string;
  amount?: number;
  tokens?: number;
  count?: number;
}

interface ToolcallDocument {
  _id: string;
  user?: string;
  userId?: string;
  tokens?: number;
  tokenCount?: number;
}

const isValidDate = (value: unknown): value is string | number | Date => {
  if (!value) return false;
  const date = new Date(value as string | number | Date);
  return !isNaN(date.getTime());
};

export function DashboardUsersList() {
  const [topUsers, setTopUsers] = useState<DashboardUser[]>([]);
  const [isLoading, setIsLoading] = useState(true);

  // Récupérer toutes les données nécessaires
  const { data: users, loading: usersLoading } =
    useCollection<LibreChatUser>("users");
  const { data: conversations, loading: conversationsLoading } =
    useCollection<LibreChatConversation>("conversations");
  const { data: balances, loading: balancesLoading } =
    useCollection<LibreChatBalance>("balances");
  const { data: messages, loading: messagesLoading } =
    useCollection<LibreChatMessage>("messages");
  const { data: tokens, loading: tokensLoading } =
    useCollection<TokenDocument>("tokens");
  const { data: toolcalls, loading: toolcallsLoading } =
    useCollection<ToolcallDocument>("toolcalls");

  const processUsers = useCallback(() => {
    if (
      !users?.length ||
      !conversations?.length ||
      !balances?.length ||
      !messages?.length
    ) {
      return;
    }

    console.log("🔄 Processing users data...");
    console.log("Users:", users.length);
    console.log("Conversations:", conversations.length);
    console.log("Balances:", balances.length);
    console.log("Messages:", messages.length);
    console.log("Tokens collection:", tokens?.length || 0);
    console.log("Toolcalls collection:", toolcalls?.length || 0);

    const processedUsers: DashboardUser[] = [];

    users.forEach((user: LibreChatUser) => {
      // Obtenir les conversations de l'utilisateur
      const userConversations = conversations.filter(
        (conv: LibreChatConversation) => conv.user === user._id
      );

      // Obtenir les messages de l'utilisateur
      const userMessages = messages.filter(
        (msg: LibreChatMessage) => msg.user === user._id
      );

      // Calculer les tokens depuis les messages
      const totalTokensFromMessages = userMessages.reduce(
        (sum: number, msg: LibreChatMessage) => sum + (msg.tokenCount || 0),
        0
      );

      // Calculer les tokens depuis les conversations de l'utilisateur
      const userConversationIds = userConversations.map(
        (conv) => conv.conversationId
      );
      const conversationMessages = messages.filter((msg: LibreChatMessage) =>
        userConversationIds.includes(msg.conversationId)
      );

      const totalTokensFromConversations = conversationMessages.reduce(
        (sum: number, msg: LibreChatMessage) => sum + (msg.tokenCount || 0),
        0
      );

      // Vérifier les collections tokens et toolcalls
      let tokensFromTokensCollection = 0;
      let tokensFromToolcalls = 0;

      if (tokens?.length) {
        const userTokens = tokens.filter(
          (token: TokenDocument) =>
            token.user === user._id || token.userId === user._id
        );
        tokensFromTokensCollection = userTokens.reduce(
          (sum: number, token: TokenDocument) => {
            return sum + (token.amount || token.tokens || token.count || 0);
          },
          0
        );
      }

      if (toolcalls?.length) {
        const userToolcalls = toolcalls.filter(
          (toolcall: ToolcallDocument) =>
            toolcall.user === user._id || toolcall.userId === user._id
        );
        tokensFromToolcalls = userToolcalls.reduce(
          (sum: number, toolcall: ToolcallDocument) => {
            return sum + (toolcall.tokens || toolcall.tokenCount || 0);
          },
          0
        );
      }

      // Obtenir les balances de l'utilisateur
      const userBalances = balances.filter(
        (balance: LibreChatBalance) => balance.user === user._id
      );

      // Trier par date de mise à jour (plus récent en premier)
      const sortedBalances = userBalances.sort((a, b) => {
        const dateA = a.updatedAt || a.createdAt;
        const dateB = b.updatedAt || b.createdAt;

        // Vérifier que les dates sont valides avant de les comparer
        if (isValidDate(dateA) && isValidDate(dateB)) {
          return (
            new Date(dateB as string | number | Date).getTime() -
            new Date(dateA as string | number | Date).getTime()
          );
        }

        // Si seulement une date existe et est valide, la privilégier
        if (isValidDate(dateA) && !isValidDate(dateB)) return -1;
        if (!isValidDate(dateA) && isValidDate(dateB)) return 1;

        // Si aucune date n'existe ou n'est valide, garder l'ordre actuel
        return 0;
      });

      // Prendre la balance la plus récente
      const latestBalance = sortedBalances[0];
      const credits = latestBalance ? latestBalance.tokenCredits || 0 : 0;

      // Calculer les tokens consommés depuis les crédits
      const INITIAL_CREDITS = 5000000;
      const creditsUsed = INITIAL_CREDITS - credits;
      const tokensFromCredits = creditsUsed > 0 ? creditsUsed : 0;

      // Prendre la valeur la plus élevée (plus précise)
      const totalTokens = Math.max(
        totalTokensFromMessages,
        totalTokensFromConversations,
        tokensFromTokensCollection,
        tokensFromToolcalls,
        tokensFromCredits
      );

      // Log de débogage très détaillé
      console.log(`👤 User ${user.name || user.email}:`, {
        conversations: userConversations.length,
        userMessages: userMessages.length,
        conversationMessages: conversationMessages.length,
        tokensFromMessages: totalTokensFromMessages,
        tokensFromConversations: totalTokensFromConversations,
        tokensFromTokensCollection: tokensFromTokensCollection,
        tokensFromToolcalls: tokensFromToolcalls,
        currentCredits: credits,
        creditsUsed: creditsUsed,
        tokensFromCredits: tokensFromCredits,
        finalTokens: totalTokens,
        messagesSample: userMessages.slice(0, 2).map((m) => ({
          tokenCount: m.tokenCount,
          model: m.model,
          isCreatedByUser: m.isCreatedByUser,
          conversationId: m.conversationId,
        })),
        conversationsSample: userConversations.slice(0, 2).map((c) => ({
          conversationId: c.conversationId,
          messagesCount: c.messages?.length || 0,
        })),
      });

      // Ajouter l'utilisateur seulement s'il a des données significatives
      if (userConversations.length > 0 || totalTokens > 0 || credits > 0) {
        processedUsers.push({
          userId: user._id,
          userName:
            user.name || user.username || user.email || "Utilisateur inconnu",
          conversations: userConversations.length,
          tokens: totalTokens,
          credits: credits,
        });
      }
    });

    // Trier par tokens consommés (décroissant) et prendre les 5 premiers
    const sortedUsers = processedUsers
      .sort((a, b) => b.tokens - a.tokens)
      .slice(0, 5);

    console.log("✅ Top 5 users processed:", sortedUsers);
    setTopUsers(sortedUsers);
    setIsLoading(false);
  }, [users, conversations, balances, messages, tokens, toolcalls]);

  useEffect(() => {
    const allDataLoaded =
      !usersLoading &&
      !conversationsLoading &&
      !balancesLoading &&
      !messagesLoading &&
      !tokensLoading &&
      !toolcallsLoading;

    if (allDataLoaded) {
      processUsers();
    } else {
      setIsLoading(true);
    }
  }, [
    usersLoading,
    conversationsLoading,
    balancesLoading,
    messagesLoading,
    tokensLoading,
    toolcallsLoading,
    processUsers,
  ]);

  if (isLoading) {
    return (
      <Card>
        <CardHeader className="flex flex-row items-center justify-between">
          <CardTitle className="flex items-center gap-2">
            <Users className="h-5 w-5" />
            Top 5 utilisateurs
          </CardTitle>
          <Button variant="outline" size="sm" disabled>
            Chargement...
          </Button>
        </CardHeader>
        <CardContent>
          <div className="space-y-3">
            {[...Array(5)].map((_, i) => (
              <div
                key={i}
                className="flex items-center justify-between p-3 border rounded-lg"
              >
                <div className="flex items-center space-x-3">
                  <div className="w-8 h-8 bg-gray-200 rounded-full animate-pulse"></div>
                  <div>
                    <div className="h-4 bg-gray-200 rounded w-24 animate-pulse"></div>
                    <div className="h-3 bg-gray-200 rounded w-16 mt-1 animate-pulse"></div>
                  </div>
                </div>
                <div className="text-right">
                  <div className="h-4 bg-gray-200 rounded w-16 animate-pulse"></div>
                  <div className="h-3 bg-gray-200 rounded w-12 mt-1 animate-pulse"></div>
                </div>
              </div>
            ))}
          </div>
        </CardContent>
      </Card>
    );
  }

  if (topUsers.length === 0) {
    return (
      <Card>
        <CardHeader className="flex flex-row items-center justify-between">
          <CardTitle className="flex items-center gap-2">
            <Users className="h-5 w-5" />
            Top 5 utilisateurs
          </CardTitle>
          <Link href="/users">
            <Button variant="outline" size="sm">
              Voir tous
            </Button>
          </Link>
        </CardHeader>
        <CardContent>
          <div className="text-center py-8 text-muted-foreground">
            Aucun utilisateur trouvé
          </div>
        </CardContent>
      </Card>
    );
  }

  return (
    <Card>
      <CardHeader className="flex flex-row items-center justify-between">
        <CardTitle className="flex items-center gap-2">
          <Users className="h-5 w-5" />
          Top 5 utilisateurs
        </CardTitle>
        <Link href="/users">
          <Button variant="outline" size="sm">
            Voir tous
          </Button>
        </Link>
      </CardHeader>
      <CardContent>
        <div className="space-y-3">
          {topUsers.map((user, index) => (
            <div
              key={user.userId}
              className="flex items-center justify-between p-3 border rounded-lg hover:bg-gray-50 transition-colors"
            >
              <div className="flex items-center space-x-3">
                <Badge
                  variant="secondary"
                  className="w-6 h-6 rounded-full p-0 flex items-center justify-center text-xs"
                >
                  {index + 1}
                </Badge>
                <div>
                  <p className="font-medium text-sm">{user.userName}</p>
                  <p className="text-xs text-muted-foreground">
                    {user.conversations} conversation
                    {user.conversations !== 1 ? "s" : ""}
                  </p>
                </div>
              </div>
              <div className="text-right">
                <p className="font-medium text-sm">
                  {user.tokens.toLocaleString()} tokens
                </p>
                <p className="text-xs text-muted-foreground">
                  {user.credits.toLocaleString()} crédits
                </p>
              </div>
            </div>
          ))}
        </div>
      </CardContent>
    </Card>
  );
}
