"use client";

import { useState, useMemo } from "react";
import { Button } from "@/components/ui/button";
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from "@/components/ui/command";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { CategoryIcon } from "@/components/ui/category-icon";
import { ChevronsUpDown, Check, Wallet, X } from "lucide-react";
import { cn } from "@/lib/utils";
import type { Account, Folder, Transaction } from "@/lib/types";
import { accountTypeIcons } from "@/components/accounts/constants";

interface AccountFilterComboboxProps {
  accounts: Account[];
  folders: Folder[];
  value: string[]; // ["all"] | [accountId, accountId, ...]
  onChange: (value: string[]) => void;
  className?: string;
  filteredTransactions?: Transaction[]; // Transactions filtered by other filters (categories, period, etc.)
}

export function AccountFilterCombobox({
  accounts,
  folders,
  value,
  onChange,
  className,
  filteredTransactions,
}: AccountFilterComboboxProps) {
  const [open, setOpen] = useState(false);

  // Calculate total amount per account based on filtered transactions
  const accountTotals = useMemo(() => {
    if (!filteredTransactions) return {};

    const totals: Record<string, number> = {};
    filteredTransactions.forEach((t) => {
      totals[t.accountId] = (totals[t.accountId] || 0) + t.amount;
    });

    return totals;
  }, [filteredTransactions]);

  const formatCurrency = (amount: number) => {
    return new Intl.NumberFormat("fr-FR", {
      style: "currency",
      currency: "EUR",
      minimumFractionDigits: 0,
      maximumFractionDigits: 0,
    }).format(amount);
  };

  // Get root folders (folders without parent) - same as folders/page.tsx
  const rootFolders = useMemo(
    () => folders.filter((f) => f.parentId === null),
    [folders],
  );

  // Get child folders for a given parent - same as FolderTreeItem
  const getChildFolders = (parentId: string) =>
    folders.filter((f) => f.parentId === parentId);

  // Get accounts in a specific folder - same as FolderTreeItem
  const getFolderAccounts = (folderId: string) =>
    accounts.filter((a) => a.folderId === folderId);

  // Get accounts without folder
  const orphanAccounts = useMemo(
    () => accounts.filter((a) => !a.folderId),
    [accounts],
  );

  const selectedAccounts = accounts.filter((a) => value.includes(a.id));
  const isAll = value.includes("all") || value.length === 0;

  // Get all accounts in a folder and its descendants recursively
  const getAllAccountsInFolder = (folderId: string): Account[] => {
    const directAccounts = getFolderAccounts(folderId);
    const childFoldersList = getChildFolders(folderId);
    const childAccounts = childFoldersList.flatMap((cf) =>
      getAllAccountsInFolder(cf.id),
    );
    return [...directAccounts, ...childAccounts];
  };

  const handleSelect = (newValue: string) => {
    if (newValue === "all") {
      onChange(["all"]);
      return;
    }

    let newSelection: string[];

    if (isAll) {
      newSelection = [newValue];
    } else if (value.includes(newValue)) {
      newSelection = value.filter((v) => v !== newValue);
      if (newSelection.length === 0) {
        newSelection = ["all"];
      }
    } else {
      newSelection = [...value, newValue];
    }

    onChange(newSelection);
  };

  const handleSelectFolder = (folderId: string) => {
    const allFolderAccounts = getAllAccountsInFolder(folderId);
    const allFolderAccountIds = allFolderAccounts.map((a) => a.id);

    if (allFolderAccountIds.length === 0) return;

    const allSelected = allFolderAccountIds.every((id) => value.includes(id));

    if (allSelected) {
      const newSelection = value.filter(
        (v) => !allFolderAccountIds.includes(v),
      );
      onChange(newSelection.length > 0 ? newSelection : ["all"]);
    } else {
      if (isAll) {
        onChange(allFolderAccountIds);
      } else {
        const newSelection = [...new Set([...value, ...allFolderAccountIds])];
        onChange(newSelection);
      }
    }
  };

  const clearSelection = () => {
    onChange(["all"]);
  };

  const isFolderSelected = (folderId: string) => {
    const folderAccounts = getAllAccountsInFolder(folderId);
    if (folderAccounts.length === 0) return false;
    return folderAccounts.every((a) => value.includes(a.id));
  };

  const isFolderPartiallySelected = (folderId: string) => {
    const folderAccounts = getAllAccountsInFolder(folderId);
    if (folderAccounts.length === 0) return false;
    const selectedCount = folderAccounts.filter((a) =>
      value.includes(a.id),
    ).length;
    return selectedCount > 0 && selectedCount < folderAccounts.length;
  };

  // Recursive render function - mirrors FolderTreeItem logic
  const renderFolder = (folder: Folder, depth: number, parentPath: string) => {
    const folderAccounts = getFolderAccounts(folder.id);
    const childFoldersList = getChildFolders(folder.id);
    const currentPath = parentPath
      ? `${parentPath} ${folder.name}`
      : folder.name;
    const paddingLeft = depth * 16 + 8;

    return (
      <div key={folder.id}>
        {/* Folder row */}
        <CommandItem
          value={`folder-${currentPath}`}
          onSelect={() => handleSelectFolder(folder.id)}
          style={{ paddingLeft: `${paddingLeft}px` }}
          className="font-medium"
        >
          <CategoryIcon icon={folder.icon} color={folder.color} size={16} />
          <span>{folder.name}</span>
          <div className="ml-auto flex items-center">
            {isFolderPartiallySelected(folder.id) && (
              <div className="h-3 w-3 rounded-sm bg-primary/50 mr-1" />
            )}
            <Check
              className={cn(
                "h-4 w-4",
                isFolderSelected(folder.id) ? "opacity-100" : "opacity-0",
              )}
            />
          </div>
        </CommandItem>

        {/* Accounts in this folder */}
        {folderAccounts.map((account) => {
          const total = accountTotals[account.id];
          const AccountIcon = accountTypeIcons[account.type];
          return (
            <CommandItem
              key={account.id}
              value={`${currentPath} ${account.name}`}
              onSelect={() => handleSelect(account.id)}
              style={{ paddingLeft: `${paddingLeft + 16}px` }}
              className="min-w-0"
            >
              <AccountIcon className="h-4 w-4 text-muted-foreground shrink-0" />
              <span className="truncate min-w-0 flex-1">{account.name}</span>
              {total !== undefined && (
                <span className="text-xs text-muted-foreground ml-1 shrink-0">
                  ({formatCurrency(total)})
                </span>
              )}
              <Check
                className={cn(
                  "ml-auto h-4 w-4 shrink-0",
                  value.includes(account.id) ? "opacity-100" : "opacity-0",
                )}
              />
            </CommandItem>
          );
        })}

        {/* Child folders - recursive */}
        {childFoldersList.map((childFolder) =>
          renderFolder(childFolder, depth + 1, currentPath),
        )}
      </div>
    );
  };

  return (
    <Popover open={open} onOpenChange={setOpen} modal={true}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox"
          aria-expanded={open}
          className={cn("justify-between min-w-0", className)}
        >
          <div className="flex items-center gap-2 min-w-0 flex-1">
            {selectedAccounts.length === 1 ? (
              <>
                {(() => {
                  const AccountIcon =
                    accountTypeIcons[selectedAccounts[0].type];
                  return (
                    <AccountIcon className="h-4 w-4 text-muted-foreground shrink-0" />
                  );
                })()}
                <span className="truncate text-left">
                  {selectedAccounts[0].name}
                </span>
              </>
            ) : selectedAccounts.length > 1 ? (
              <>
                <Wallet className="h-4 w-4 text-muted-foreground shrink-0" />
                <span className="truncate text-left">
                  {selectedAccounts.length} comptes
                </span>
              </>
            ) : (
              <>
                <Wallet className="h-4 w-4 text-muted-foreground shrink-0" />
                <span className="text-muted-foreground truncate text-left">
                  Tous les comptes
                </span>
              </>
            )}
          </div>
          <div className="flex items-center gap-1 shrink-0 ml-2">
            {!isAll && (
              <div
                role="button"
                className="h-4 w-4 rounded-sm hover:bg-muted flex items-center justify-center"
                onClick={(e) => {
                  e.stopPropagation();
                  clearSelection();
                }}
              >
                <X className="h-3 w-3" />
              </div>
            )}
            <ChevronsUpDown className="h-4 w-4 shrink-0 opacity-50" />
          </div>
        </Button>
      </PopoverTrigger>
      <PopoverContent
        className="w-[380px] p-0"
        align="start"
        onOpenAutoFocus={(e) => e.preventDefault()}
      >
        <Command>
          <CommandInput placeholder="Rechercher..." />
          <CommandList className="max-h-[300px]">
            <CommandEmpty>Aucun compte trouvé.</CommandEmpty>
            <CommandGroup>
              <CommandItem value="all" onSelect={() => handleSelect("all")}>
                <Wallet className="h-4 w-4 text-muted-foreground" />
                <span>Tous les comptes</span>
                {filteredTransactions && (
                  <span className="text-xs text-muted-foreground ml-1">
                    (
                    {formatCurrency(
                      filteredTransactions.reduce(
                        (sum, t) => sum + t.amount,
                        0,
                      ),
                    )}
                    )
                  </span>
                )}
                <Check
                  className={cn(
                    "ml-auto h-4 w-4",
                    isAll ? "opacity-100" : "opacity-0",
                  )}
                />
              </CommandItem>
            </CommandGroup>

            <CommandGroup>
              {rootFolders.map((folder) => renderFolder(folder, 0, ""))}
            </CommandGroup>

            {orphanAccounts.length > 0 && (
              <CommandGroup heading="Sans dossier">
                {orphanAccounts.map((account) => {
                  const total = accountTotals[account.id];
                  const AccountIcon = accountTypeIcons[account.type];
                  return (
                    <CommandItem
                      key={account.id}
                      value={`sans-dossier ${account.name}`}
                      onSelect={() => handleSelect(account.id)}
                      className="min-w-0"
                    >
                      <AccountIcon className="h-4 w-4 text-muted-foreground shrink-0" />
                      <span className="truncate min-w-0 flex-1">
                        {account.name}
                      </span>
                      {total !== undefined && (
                        <span className="text-xs text-muted-foreground ml-1 shrink-0">
                          ({formatCurrency(total)})
                        </span>
                      )}
                      <Check
                        className={cn(
                          "ml-auto h-4 w-4 shrink-0",
                          value.includes(account.id)
                            ? "opacity-100"
                            : "opacity-0",
                        )}
                      />
                    </CommandItem>
                  );
                })}
              </CommandGroup>
            )}
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}
