import { Button } from "@/components/ui/button";
import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
import { Input } from "@/components/ui/input";
import { Checkbox } from "@/components/ui/checkbox";
import { Textarea } from "@/components/ui/textarea";
import { ArrowBigDownDash, ArrowBigUpDash, Brackets, CaseSensitive, Filter, Languages, LocateFixed, MoreVertical, PencilLine, Trash2 } from "lucide-react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import type React from "react";
import { TableVirtuoso, type TableVirtuosoHandle } from "react-virtuoso";
import { toast } from "sonner";
import { useClipboard } from "@/hooks/use-clipboard";
import { useTableOptionState } from "./use-table-option-state";
import type { FlatEntry } from "@/lib/i18n-structure";
import type { TranslationInlineEditHandlers } from "@/hooks/biz/use-translation-inline-edit";

interface EditorTableProps {
  entries: FlatEntry[];
  languages: string[];
  selected: Set<string>;
  setSelected: React.Dispatch<React.SetStateAction<Set<string>>>;
  inlineEdit: TranslationInlineEditHandlers;
  onOpenAddEntry: (path: string, position: "above" | "below") => void;
  onOpenAiTranslate: (path: string) => void;
  onOpenBulkAiTranslate: () => void;
  onOpenRenameEntry: (path: string) => void;
  onMoveEntry: (path: string, offset: number) => Promise<void> | void;
  onDeleteEntry: (path: string) => Promise<void> | void;
  onDeleteSelected: (paths: string[]) => Promise<void> | void;
  maxAiItems?: number;
}

export default function EditorTable({
  entries,
  languages,
  selected,
  setSelected,
  inlineEdit,
  onOpenAddEntry,
  onOpenAiTranslate,
  onOpenBulkAiTranslate,
  onOpenRenameEntry,
  onMoveEntry,
  onDeleteEntry,
  onDeleteSelected,
  maxAiItems = 50,
}: EditorTableProps) {
  const { copy } = useClipboard();

  const [visibleLangs, setVisibleLangs] = useState<Set<string>>(new Set());

  useEffect(() => {
    setVisibleLangs(new Set(languages));
  }, [languages]);

  const virtuosoRef = useRef<TableVirtuosoHandle | null>(null);
  const scrollerRootRef = useRef<HTMLElement | Window | null>(null);

  const {
    query, setQuery,
    caseSensitive, setCaseSensitive,
    fullMatch, setFullMatch,
  } = useTableOptionState();

  const [moveCountUp, setMoveCountUp] = useState(1);
  const [moveCountDown, setMoveCountDown] = useState(1);

  const allSelected = useMemo(() => entries.length > 0 && selected.size === entries.length, [entries, selected]);
  const MAX_AI_ITEMS = maxAiItems;

  const highlightRow = useCallback((index: number) => {
    const tryFindAndAnimate = (attempt = 0) => {
      const root = scrollerRootRef.current as HTMLElement | null;
      if (!root) return;
      const row = root.querySelector(`tr[data-item-index="${index}"]`) as HTMLTableRowElement | null;
      if (row) {
        row.animate(
          [
            { backgroundColor: "rgba(250, 204, 21, 0.6)" },
            { backgroundColor: "transparent" },
            { backgroundColor: "rgba(250, 204, 21, 0.6)" },
            { backgroundColor: "transparent" },
          ],
          { duration: 1200, easing: "ease-in-out" }
        );
        return;
      }
      if (attempt < 10) {
        setTimeout(() => tryFindAndAnimate(attempt + 1), 50);
      }
    };
    requestAnimationFrame(() => tryFindAndAnimate(0));
  }, []);

  const scrollToQuery = useCallback((ev: React.FormEvent<HTMLFormElement>) => {
    ev.preventDefault();
    ev.stopPropagation();

    if (!query) return;
    const idx = entries.findIndex((e) => {
      const hay = caseSensitive ? e.path : e.path.toLowerCase();
      const needle = caseSensitive ? query : query.toLowerCase();
      return fullMatch ? hay === needle : hay.includes(needle);
    });
    if (idx >= 0) {
      virtuosoRef.current?.scrollIntoView({ index: idx, align: "center", done: () => highlightRow(idx) });
    }
  }, [caseSensitive, entries, fullMatch, highlightRow, query]);

  const displayedLanguages = useMemo(() => languages.filter((l) => visibleLangs.has(l)), [languages, visibleLangs]);
  const tableWidth = useMemo(() => (displayedLanguages.length * 200) + 36 + 60 + 300, [displayedLanguages.length]);

  const virtuosoComponents = useMemo(() => ({
    Table: ({ style, ...props }: React.TableHTMLAttributes<HTMLTableElement>) => <table className="min-w-full text-sm table-fixed" {...props} style={{ ...style, width: tableWidth }} />,
    TableHead: (props: React.HTMLAttributes<HTMLTableSectionElement>) => <thead className="bg-muted" {...props} />,
    TableRow: (props: React.HTMLAttributes<HTMLTableRowElement>) => <tr className="border-t" {...props} />,
    TableBody: (props: React.HTMLAttributes<HTMLTableSectionElement>) => <tbody {...props} />,
    TableFoot: (props: React.HTMLAttributes<HTMLTableSectionElement>) => <tfoot {...props} />,
  }), [tableWidth]);

  const headerContent = useCallback(() => (
    <tr>
      <th style={{ width: 36 }} className="sticky left-0 text-left px-3 py-2 bg-muted">
        <Checkbox
          checked={allSelected}
          onCheckedChange={(checked) => {
            const next = new Set<string>();
            if (checked) {
              for (const en of entries) next.add(en.path);
            }
            setSelected(next);
          }}
        />
      </th>
      <th style={{ width: 300 }} className="text-left px-3 py-2">翻译条目名称</th>
      {displayedLanguages.map((lang) => (
        <th key={lang} style={{ width: 200 }} className="text-left px-3 py-2">{lang}</th>
      ))}
      <th style={{ width: 60 }} className="sticky right-0 text-left px-3 py-2 bg-muted">操作</th>
    </tr>
  ), [allSelected, displayedLanguages, entries, setSelected]);

  const renderItemContent = useCallback((_idx: number, entry: FlatEntry) => {
    const handleCopy = () => {
      copy(entry.path);
      toast.success("复制成功");
    };

    return (
      <>
        <td className="sticky left-0 px-3 py-2 bg-white">
          <Checkbox
            checked={selected.has(entry.path)}
            onCheckedChange={(checked) => {
              setSelected((prev) => {
                const next = new Set(prev);
                if (checked) next.add(entry.path); else next.delete(entry.path);
                return next;
              });
            }}
          />
        </td>
        <td className="px-3 py-2 font-mono wrap-break-word">
          <button type="button" className="w-full text-left min-h-8 leading-normal px-2 rounded hover:bg-accent" onClick={handleCopy} title="点击复制">
            {entry.path}
          </button>
        </td>
        {displayedLanguages.map((lang) => {
          const isEditing = inlineEdit.isEditingCell(entry.path, lang);
          const isSaving = inlineEdit.isSavingCell(entry.path, lang);
          const displayValue = inlineEdit.getDisplayValue(entry.path, lang);

          return (
            <td key={`${entry.path}:${lang}`} className="px-3 py-2 text-foreground/90 align-top">
              {isEditing ? (
                <Textarea
                  ref={inlineEdit.inputRef}
                  value={inlineEdit.editingValue}
                  onChange={(e) => inlineEdit.setEditingValue(e.target.value)}
                  onBlur={() => { void inlineEdit.saveEdit(); }}
                  onKeyDown={inlineEdit.handleKeyDown}
                  disabled={isSaving}
                  className="leading-normal px-2 py-0"
                />
              ) : (
                <button
                  type="button"
                  className="w-full text-left min-h-8 leading-normal px-2 rounded hover:bg-accent"
                  onClick={() => inlineEdit.startEdit(entry.path, lang)}
                  title="点击编辑"
                >
                  {displayValue || <span className="text-destructive">点击编辑</span>}
                </button>
              )}
            </td>
          );
        })}
        <td className="sticky right-0 px-3 py-2 align-top bg-white">
          <DropdownMenu modal={false}>
            <DropdownMenuTrigger asChild>
              <Button size="sm" variant="outline">
                <MoreVertical />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end" className="w-64">
              <DropdownMenuItem onClick={() => onOpenAddEntry(entry.path, "below")}>
                <ArrowBigDownDash />
                在下面新增
              </DropdownMenuItem>
              <DropdownMenuItem onClick={() => onOpenAddEntry(entry.path, "above")}>
                <ArrowBigUpDash />
                在上面新增
              </DropdownMenuItem>
              <DropdownMenuSeparator />
              <DropdownMenuItem onClick={() => onOpenAiTranslate(entry.path)}>
                <Languages />
                AI 翻译
              </DropdownMenuItem>
              <DropdownMenuSeparator />
              <DropdownMenuItem onClick={() => onOpenRenameEntry(entry.path)}>
                <PencilLine />
                重命名
              </DropdownMenuItem>
              <DropdownMenuSeparator />
              <DropdownMenuItem
                onSelect={async () => {
                  await onMoveEntry(entry.path, -moveCountUp);
                }}
              >
                <ArrowBigUpDash />
                <span className="whitespace-nowrap">向上移动</span>
                <Input
                  type="number"
                  min={1}
                  value={moveCountUp}
                  onChange={(e) => {
                    const n = parseInt(e.target.value, 10);
                    setMoveCountUp(Number.isFinite(n) && n > 0 ? n : 1);
                  }}
                  className="h-7 w-16"
                  onClick={(e) => {
                    e.preventDefault();
                    e.stopPropagation();
                  }}
                />
                个条目
              </DropdownMenuItem>
              <DropdownMenuItem
                onSelect={async () => {
                  await onMoveEntry(entry.path, moveCountDown);
                }}
              >
                <ArrowBigDownDash />
                <span className="whitespace-nowrap">向下移动</span>
                <Input
                  type="number"
                  min={1}
                  value={moveCountDown}
                  onChange={(e) => {
                    const n = parseInt(e.target.value, 10);
                    setMoveCountDown(Number.isFinite(n) && n > 0 ? n : 1);
                  }}
                  className="h-7 w-16"
                  onClick={(e) => {
                    e.preventDefault();
                    e.stopPropagation();
                  }}
                />
                个条目
              </DropdownMenuItem>
              <DropdownMenuSeparator />
              <DropdownMenuItem
                variant="destructive"
                onClick={async () => {
                  if (!confirm("确认删除该条目？此操作会移除所有语言下的该键")) return;
                  await onDeleteEntry(entry.path);
                }}
              >
                <Trash2 />
                删除
              </DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        </td>
      </>
    );
  }, [copy, displayedLanguages, inlineEdit, moveCountDown, moveCountUp, onDeleteEntry, onMoveEntry, onOpenAddEntry, onOpenAiTranslate, onOpenRenameEntry, selected, setSelected]);


  return (
    <div className="h-full flex flex-col">
      <form className="mb-3 flex items-center gap-2" onSubmit={scrollToQuery}>
        <Input placeholder="搜索翻译条目名称" value={query} onChange={(e) => setQuery(e.target.value)} />
        <Button
          type="button"
          variant={fullMatch ? "default" : "outline"}
          onClick={() => setFullMatch((v) => !v)}
          title="切换全量匹配/模糊匹配"
        >
          <Brackets />
          {fullMatch ? "全量匹配" : "模糊匹配"}
        </Button>
        <Button
          type="button"
          variant={caseSensitive ? "default" : "outline"}
          onClick={() => setCaseSensitive((v) => !v)}
          title="切换大小写敏感"
        >
          <CaseSensitive />
          {caseSensitive ? "区分大小写" : "忽略大小写"}
        </Button>
        <Button type="submit">
          <LocateFixed />
          定位
        </Button>
      </form>
      <div className="mb-2 flex items-center gap-2">
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button variant="outline" title="过滤显示的语言列">
              <Filter />
              语言过滤
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="start" className="w-48">
            <DropdownMenuItem onClick={() => setVisibleLangs(new Set(languages))}>
              全部显示
            </DropdownMenuItem>
            <DropdownMenuSeparator />
            {languages.map((lang) => {
              const checked = visibleLangs.has(lang);
              return (
                <DropdownMenuCheckboxItem
                  key={lang}
                  onSelect={(e) => e.preventDefault()}
                  checked={checked}
                  onCheckedChange={(v) => {
                    setVisibleLangs((prev) => {
                      const next = new Set(prev);
                      if (v) next.add(lang); else next.delete(lang);
                      return next;
                    });
                  }}
                >
                  {lang}
                </DropdownMenuCheckboxItem>
              );
            })}
          </DropdownMenuContent>
        </DropdownMenu>
        <Button
          variant="outline"
          disabled={selected.size === 0 || selected.size > MAX_AI_ITEMS}
          onClick={onOpenBulkAiTranslate}
          title={selected.size > MAX_AI_ITEMS ? `最多支持 ${MAX_AI_ITEMS} 条` : "对所选条目进行 AI 翻译"}
        >
          <Languages />
          AI 翻译所选（{selected.size}）
        </Button>
        {selected.size > MAX_AI_ITEMS && (
          <span className="text-xs text-red-600">最多支持 {MAX_AI_ITEMS} 条</span>
        )}
        <Button
          variant="outline-destructive"
          disabled={selected.size === 0}
          onClick={async () => {
            if (!confirm(`确认删除所选 ${selected.size} 个条目？此操作会移除所有语言下的这些键`)) return;
            await onDeleteSelected(Array.from(selected));
          }}
          title="删除所选条目"
        >
          <Trash2 />
          删除所选
        </Button>
      </div>
      <div className="flex-1 border rounded-md">
        <TableVirtuoso
          ref={virtuosoRef}
          data={entries}
          fixedHeaderContent={headerContent}
          itemContent={renderItemContent}
          components={virtuosoComponents}
          computeItemKey={(_index, entry) => entry.path}
          scrollerRef={(el) => { scrollerRootRef.current = el; }}
        />
      </div>
    </div>
  );
}
