"use client";

import { useEffect, useRef, useState, useCallback } from "react";
import { useVirtualizer } from "@tanstack/react-virtual";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Checkbox } from "@/components/ui/checkbox";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import {
  Tooltip,
  TooltipContent,
  TooltipTrigger,
} from "@/components/ui/tooltip";
import { CategoryCombobox } from "@/components/ui/category-combobox";
import {
  CheckCircle2,
  Circle,
  MoreVertical,
  ArrowUpDown,
  Wand2,
  Trash2,
} from "lucide-react";
import { DropdownMenuSeparator } from "@/components/ui/dropdown-menu";
import { cn } from "@/lib/utils";
import type { Transaction, Account, Category } from "@/lib/types";

type SortField = "date" | "amount" | "description";
type SortOrder = "asc" | "desc";

interface TransactionTableProps {
  transactions: Transaction[];
  accounts: Account[];
  categories: Category[];
  selectedTransactions: Set<string>;
  sortField: SortField;
  sortOrder: SortOrder;
  onSortChange: (field: SortField) => void;
  onToggleSelectAll: () => void;
  onToggleSelectTransaction: (id: string) => void;
  onToggleReconciled: (id: string) => void;
  onMarkReconciled: (id: string) => void;
  onSetCategory: (transactionId: string, categoryId: string | null) => void;
  onCreateRule: (transaction: Transaction) => void;
  onDelete: (id: string) => void;
  formatCurrency: (amount: number) => string;
  formatDate: (dateStr: string) => string;
}

const ROW_HEIGHT = 72; // Hauteur approximative d'une ligne

function DescriptionWithTooltip({ description }: { description: string }) {
  const ref = useRef<HTMLParagraphElement>(null);
  const [isTruncated, setIsTruncated] = useState(false);

  useEffect(() => {
    const checkTruncation = () => {
      const element = ref.current;
      if (!element) return;
      
      // Check if text is truncated by comparing scrollWidth and clientWidth
      // Add a small threshold (1px) to account for rounding issues
      const truncated = element.scrollWidth > element.clientWidth + 1;
      setIsTruncated(truncated);
    };

    // Check multiple times to handle virtualization timing
    checkTruncation();
    const timeout1 = setTimeout(checkTruncation, 0);
    const timeout2 = setTimeout(checkTruncation, 50);
    const timeout3 = setTimeout(checkTruncation, 150);
    const timeout4 = setTimeout(checkTruncation, 300);

    // Use ResizeObserver to detect size changes
    let resizeObserver: ResizeObserver | null = null;
    if (ref.current && typeof ResizeObserver !== "undefined") {
      resizeObserver = new ResizeObserver(() => {
        // Small delay for ResizeObserver to ensure layout is complete
        setTimeout(checkTruncation, 0);
      });
      resizeObserver.observe(ref.current);
    }

    return () => {
      clearTimeout(timeout1);
      clearTimeout(timeout2);
      clearTimeout(timeout3);
      clearTimeout(timeout4);
      if (resizeObserver) {
        resizeObserver.disconnect();
      }
    };
  }, [description]);

  const content = (
    <span ref={ref} className="text-xs text-muted-foreground truncate block">
      {description}
    </span>
  );

  // Show tooltip if truncated or if description is reasonably long
  const shouldShowTooltip = isTruncated || description.length > 25;

  if (!shouldShowTooltip) {
    return content;
  }

  return (
    <Tooltip delayDuration={200}>
      <TooltipTrigger asChild>
        {content}
      </TooltipTrigger>
      <TooltipContent 
        side="top" 
        align="start"
        className="max-w-md break-words"
        sideOffset={5}
      >
        {description}
      </TooltipContent>
    </Tooltip>
  );
}

export function TransactionTable({
  transactions,
  accounts,
  categories,
  selectedTransactions,
  sortField: _sortField,
  sortOrder: _sortOrder,
  onSortChange,
  onToggleSelectAll,
  onToggleSelectTransaction,
  onToggleReconciled,
  onMarkReconciled,
  onSetCategory,
  onCreateRule,
  onDelete,
  formatCurrency,
  formatDate,
}: TransactionTableProps) {
  const [focusedIndex, setFocusedIndex] = useState<number | null>(null);
  const parentRef = useRef<HTMLDivElement>(null);

  const virtualizer = useVirtualizer({
    count: transactions.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => ROW_HEIGHT,
    overscan: 10,
  });

  const handleRowClick = useCallback(
    (index: number, transactionId: string) => {
      setFocusedIndex(index);
      onMarkReconciled(transactionId);
    },
    [onMarkReconciled]
  );

  const handleKeyDown = useCallback(
    (e: KeyboardEvent) => {
      if (focusedIndex === null || transactions.length === 0) return;

      if (e.key === "ArrowDown") {
        e.preventDefault();
        const newIndex = Math.min(focusedIndex + 1, transactions.length - 1);
        if (newIndex !== focusedIndex) {
          setFocusedIndex(newIndex);
          onMarkReconciled(transactions[newIndex].id);
          virtualizer.scrollToIndex(newIndex, {
            align: "start",
          });
        }
      } else if (e.key === "ArrowUp") {
        e.preventDefault();
        const newIndex = Math.max(focusedIndex - 1, 0);
        if (newIndex !== focusedIndex) {
          setFocusedIndex(newIndex);
          onMarkReconciled(transactions[newIndex].id);
          virtualizer.scrollToIndex(newIndex, {
            align: "start",
          });
        }
      }
    },
    [focusedIndex, transactions, onMarkReconciled, virtualizer]
  );

  useEffect(() => {
    document.addEventListener("keydown", handleKeyDown);
    return () => document.removeEventListener("keydown", handleKeyDown);
  }, [handleKeyDown]);

  // Reset focused index when transactions change
  useEffect(() => {
    setFocusedIndex(null);
  }, [transactions.length]);

  const getAccount = (accountId: string) => {
    return accounts.find((a) => a.id === accountId);
  };

  return (
    <Card>
      <CardContent className="p-0">
        {transactions.length === 0 ? (
          <div className="flex flex-col items-center justify-center py-12">
            <p className="text-muted-foreground">Aucune transaction trouvée</p>
          </div>
        ) : (
          <div className="overflow-x-auto">
            {/* Header fixe */}
            <div className="sticky top-0 z-10 bg-[var(--card)] border-b border-border">
              <div className="grid grid-cols-[auto_120px_2fr_150px_180px_140px_auto_auto] gap-0">
                <div className="p-3">
                  <Checkbox
                    checked={
                      selectedTransactions.size === transactions.length &&
                      transactions.length > 0
                    }
                    onCheckedChange={onToggleSelectAll}
                  />
                </div>
                <div className="p-3">
                  <button
                    onClick={() => onSortChange("date")}
                    className="flex items-center gap-1 text-sm font-medium text-muted-foreground hover:text-foreground"
                  >
                    Date
                    <ArrowUpDown className="w-3 h-3" />
                  </button>
                </div>
                <div className="p-3">
                  <button
                    onClick={() => onSortChange("description")}
                    className="flex items-center gap-1 text-sm font-medium text-muted-foreground hover:text-foreground"
                  >
                    Description
                    <ArrowUpDown className="w-3 h-3" />
                  </button>
                </div>
                <div className="p-3 text-sm font-medium text-muted-foreground">
                  Compte
                </div>
                <div className="p-3 text-sm font-medium text-muted-foreground">
                  Catégorie
                </div>
                <div className="p-3 text-right">
                  <button
                    onClick={() => onSortChange("amount")}
                    className="flex items-center gap-1 text-sm font-medium text-muted-foreground hover:text-foreground ml-auto"
                  >
                    Montant
                    <ArrowUpDown className="w-3 h-3" />
                  </button>
                </div>
                <div className="p-3 text-center text-sm font-medium text-muted-foreground">
                  Pointé
                </div>
                <div className="p-3"></div>
              </div>
            </div>
            {/* Body virtualisé */}
            <div
              ref={parentRef}
              className="overflow-auto"
              style={{ height: "calc(100vh - 400px)", minHeight: "400px" }}
            >
              <div
                style={{
                  height: `${virtualizer.getTotalSize()}px`,
                  width: "100%",
                  position: "relative",
                }}
              >
                {virtualizer.getVirtualItems().map((virtualRow) => {
                  const transaction = transactions[virtualRow.index];
                  const account = getAccount(transaction.accountId);
                  const isFocused = focusedIndex === virtualRow.index;

                  return (
                    <div
                      key={transaction.id}
                      data-index={virtualRow.index}
                      ref={virtualizer.measureElement}
                      style={{
                        position: "absolute",
                        top: 0,
                        left: 0,
                        width: "100%",
                        transform: `translateY(${virtualRow.start}px)`,
                      }}
                      onClick={() => handleRowClick(virtualRow.index, transaction.id)}
                      className={cn(
                        "grid grid-cols-[auto_120px_2fr_150px_180px_140px_auto_auto] gap-0 border-b border-border hover:bg-muted/50 cursor-pointer",
                        transaction.isReconciled && "bg-emerald-500/5",
                        isFocused && "bg-primary/10 ring-1 ring-primary/30"
                      )}
                    >
                      <div className="p-3">
                        <Checkbox
                          checked={selectedTransactions.has(transaction.id)}
                          onCheckedChange={() =>
                            onToggleSelectTransaction(transaction.id)
                          }
                        />
                      </div>
                      <div className="p-3 text-sm text-muted-foreground whitespace-nowrap">
                        {formatDate(transaction.date)}
                      </div>
                      <div className="p-3 min-w-0 overflow-hidden" onClick={(e) => e.stopPropagation()}>
                        <p className="font-medium text-sm truncate">
                          {transaction.description}
                        </p>
                        {transaction.memo && (
                          <DescriptionWithTooltip description={transaction.memo} />
                        )}
                      </div>
                      <div className="p-3 text-sm text-muted-foreground">
                        {account?.name || "-"}
                      </div>
                      <div className="p-3" onClick={(e) => e.stopPropagation()}>
                        <CategoryCombobox
                          categories={categories}
                          value={transaction.categoryId}
                          onChange={(categoryId) =>
                            onSetCategory(transaction.id, categoryId)
                          }
                          showBadge
                          align="start"
                        />
                      </div>
                      <div
                        className={cn(
                          "p-3 text-right font-semibold tabular-nums",
                          transaction.amount >= 0
                            ? "text-emerald-600"
                            : "text-red-600"
                        )}
                      >
                        {transaction.amount >= 0 ? "+" : ""}
                        {formatCurrency(transaction.amount)}
                      </div>
                      <div className="p-3 text-center" onClick={(e) => e.stopPropagation()}>
                        <button
                          onClick={() => onToggleReconciled(transaction.id)}
                          className="p-1 hover:bg-muted rounded"
                        >
                          {transaction.isReconciled ? (
                            <CheckCircle2 className="w-5 h-5 text-emerald-600" />
                          ) : (
                            <Circle className="w-5 h-5 text-muted-foreground" />
                          )}
                        </button>
                      </div>
                      <div className="p-3" onClick={(e) => e.stopPropagation()}>
                        <DropdownMenu>
                          <DropdownMenuTrigger asChild>
                            <Button
                              variant="ghost"
                              size="icon"
                              className="h-8 w-8"
                            >
                              <MoreVertical className="w-4 h-4" />
                            </Button>
                          </DropdownMenuTrigger>
                          <DropdownMenuContent align="end">
                            <DropdownMenuItem
                              onClick={(e) => {
                                e.stopPropagation();
                                onToggleReconciled(transaction.id);
                              }}
                            >
                              {transaction.isReconciled ? (
                                <>
                                  <Circle className="w-4 h-4 mr-2" />
                                  Dépointer
                                </>
                              ) : (
                                <>
                                  <CheckCircle2 className="w-4 h-4 mr-2" />
                                  Pointer
                                </>
                              )}
                            </DropdownMenuItem>
                            <DropdownMenuSeparator />
                            <DropdownMenuItem
                              onClick={(e) => {
                                e.stopPropagation();
                                onCreateRule(transaction);
                              }}
                            >
                              <Wand2 className="w-4 h-4 mr-2" />
                              Créer une règle
                            </DropdownMenuItem>
                            <DropdownMenuSeparator />
                            <DropdownMenuItem
                              onClick={(e) => {
                                e.stopPropagation();
                                if (
                                  confirm(
                                    `Êtes-vous sûr de vouloir supprimer cette transaction ?\n\n${transaction.description}\n${formatCurrency(transaction.amount)}`
                                  )
                                ) {
                                  onDelete(transaction.id);
                                }
                              }}
                              className="text-red-600 focus:text-red-600"
                            >
                              <Trash2 className="w-4 h-4 mr-2" />
                              Supprimer
                            </DropdownMenuItem>
                          </DropdownMenuContent>
                        </DropdownMenu>
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          </div>
        )}
      </CardContent>
    </Card>
  );
}

