"use client";

import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Loader2, Table, X, Zap } from "lucide-react";
import { useConvexAuth, useMutation, useQuery } from "convex/react";
import type { DocumentTable, TableRowData } from "@/types/online-table";
import {
  DEFAULT_TABLE_COLUMNS,
  DEFAULT_TABLE_ROWS,
  DEFAULT_TABLE_SCHEMA,
  createDefaultTableSnapshot,
  saveOnlineTable,
} from "@/lib/online-table";
import { api } from "@/lib/convex/api";
import { isConvexEnabled } from "@/lib/convex/enabled";
import { useDebouncedCallback } from "@/hooks/use-debounced-callback";
import { useLuckysheetLoader } from "@/components/online-table/useLuckysheetLoader";
import { extractRowsForPreview } from "@/components/online-table/utils";

interface FullScreenTableEditorProps {
  tableId: string;
  onClose: () => void;
}

// Luckysheet 容器的 ID
const LUCKY_SHEET_CONTAINER_ID = "luckysheet-editor-container";

type LuckysheetSelection =
  | {
      row?: [number, number];
      column?: [number, number];
      row_focus?: number;
      column_focus?: number;
    }
  | undefined;

const ENABLE_SINGLE_CLICK_EDIT = true;

const isPrintableKey = (event: KeyboardEvent) => {
  if (event.defaultPrevented) return false;
  if (event.metaKey || event.ctrlKey || event.altKey) return false;
  if (event.key === "Enter" || event.key === "Tab" || event.key === "Escape") return false;
  if (event.key.length === 1) return true;
  return event.key === "Process" || event.key === "Unidentified";
};

const isInlineEditorVisible = () => {
  const inputBox = document.getElementById("luckysheet-input-box");
  if (!inputBox) {
    return false;
  }
  const style = window.getComputedStyle(inputBox);
  return style.top !== "-10000px" && style.display !== "none";
};

const isElementInsideEditorToolbar = (element: HTMLElement | null) => {
  if (!element) return false;
  if (element.closest(".luckysheet-wa-editor")) {
    return true;
  }
  if (element.closest(".luckysheet-modal-dialog")) {
    return true;
  }
  return false;
};

const FullScreenTableEditor: React.FC<FullScreenTableEditorProps> = ({ tableId, onClose }) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const isApplyingSnapshotRef = useRef(false);
  const hasInitializedRef = useRef(false);
  const lastTableIdRef = useRef<string | null>(null);
  const isLuckysheetReady = useLuckysheetLoader();
  const [tableData, setTableData] = useState<DocumentTable | null>(null);
  const [isTableLoading, setIsTableLoading] = useState(true);
  const [tableError, setTableError] = useState<string | null>(null);
  const [isSaving, setIsSaving] = useState(false);
  const [hasPendingChanges, setHasPendingChanges] = useState(false);
  const [saveError, setSaveError] = useState<string | null>(null);
  const [lastSyncedAt, setLastSyncedAt] = useState<number | null>(null);
  const persistSnapshotRef = useRef<((reason: "auto" | "close") => Promise<void>) | null>(null);
  const lastLocalPersistAtRef = useRef<number>(0);
  const lastPointerDownInGridRef = useRef(false);
  const savingHintTimerRef = useRef<number | null>(null);
  const [showSavingHint, setShowSavingHint] = useState(false);
  const [isRenaming, setIsRenaming] = useState(false);
  const [renameValue, setRenameValue] = useState("");
  const [isSavingTitle, setIsSavingTitle] = useState(false);

  const convexEnabled = isConvexEnabled();
  const { isAuthenticated } = useConvexAuth();
  const currentUser = useQuery(api.users.currentUser, convexEnabled && isAuthenticated ? {} : "skip");
  const userId =
    currentUser && typeof currentUser === "object" && typeof (currentUser as any)._id === "string"
      ? String((currentUser as any)._id)
      : "";
  const tableFromConvex = useQuery(
    api.tables.get,
    convexEnabled && userId && tableId ? { userId, tableId } : "skip",
  );
  const updateTable = useMutation(api.tables.update);

  const startSavingHint = useCallback(() => {
    if (savingHintTimerRef.current !== null) return;
    savingHintTimerRef.current = window.setTimeout(() => {
      setShowSavingHint(true);
    }, 700);
  }, []);

  const stopSavingHint = useCallback(() => {
    if (savingHintTimerRef.current !== null) {
      clearTimeout(savingHintTimerRef.current);
      savingHintTimerRef.current = null;
    }
    setShowSavingHint(false);
  }, []);

  useEffect(() => {
    if (typeof window !== "undefined") {
      (window as unknown as { __wolaiFullScreenState?: { isLoaded: boolean; tableReady: boolean } }).__wolaiFullScreenState = {
        isLoaded: isLuckysheetReady,
        tableReady: !!tableData,
      };
    }
  }, [isLuckysheetReady, tableData]);

  const fetchTable = useCallback((id: string) => {
    setIsTableLoading(true);
    setTableError(null);
    setTableData(null);
    fetch(`/api/tables/${id}`)
      .then((response) => {
        if (!response.ok) {
          throw new Error(`Failed to load table ${id}`);
        }
        return response.json() as Promise<DocumentTable>;
      })
      .then((data) => {
        setTableData(data);
      })
      .catch((error) => {
        console.error(error);
        setTableError("无法加载表格数据，请稍后重试。");
        setTableData(null);
      })
      .finally(() => setIsTableLoading(false));
  }, []);

  useEffect(() => {
    hasInitializedRef.current = false;
    lastTableIdRef.current = tableId;
  }, [tableId]);

  useEffect(() => {
    if (convexEnabled) {
      if (tableFromConvex === undefined) {
        setIsTableLoading(true);
        setTableError(null);
        return;
      }
      if (tableFromConvex === null) {
        setIsTableLoading(false);
        setTableError("无法加载表格数据，请稍后重试。");
        setTableData(null);
        return;
      }
      // 避免“本地保存 -> 订阅回推 -> 立刻重建 luckysheet”导致的闪烁/选区丢失
      if (Date.now() - lastLocalPersistAtRef.current < 1500) {
        setIsTableLoading(false);
        return;
      }
      setTableError(null);
      setTableData(tableFromConvex as unknown as DocumentTable);
      setIsTableLoading(false);
      return;
    }

    fetchTable(tableId);
  }, [convexEnabled, fetchTable, tableFromConvex, tableId]);

  useEffect(() => {
    if (tableData?.title !== undefined) {
      setRenameValue(tableData.title ?? "");
    }
  }, [tableData?.title]);

  const luckysheetSheets = useMemo(() => {
    if (tableData?.snapshot?.luckysheet && Array.isArray(tableData.snapshot.luckysheet) && tableData.snapshot.luckysheet.length > 0) {
      return tableData.snapshot.luckysheet;
    }
    const snapshot = createDefaultTableSnapshot(tableData?.schema ?? DEFAULT_TABLE_SCHEMA);
    return snapshot.luckysheet ?? [];
  }, [tableData]);

  const normalizedSheets = useMemo(() => {
    return luckysheetSheets.map((sheet: any) => ({
      ...sheet,
      celldata: Array.isArray(sheet.celldata) ? sheet.celldata : [],
      config: {
        ...(sheet.config ?? {}),
        rowlen: { ...(sheet.config?.rowlen ?? {}) },
        columnlen: { ...(sheet.config?.columnlen ?? {}) },
        merge: { ...(sheet.config?.merge ?? {}) },
      },
    }));
  }, [luckysheetSheets]);

  const persistSnapshot = useCallback(async (reason: "auto" | "close") => {
    if (!tableData || !window.luckysheet || typeof window.luckysheet.getluckysheetfile !== "function") {
      return;
    }
    startSavingHint();
    setIsSaving(true);
    setSaveError(null);
    try {
      const luckysheetData = window.luckysheet.getluckysheetfile?.() ?? luckysheetSheets;
      const rows = extractRowsForPreview(
        luckysheetData,
        (tableData.schema?.columns ?? []).map((item) => ({ id: item.id })),
      ).filter((row) => row && typeof row === "object" && Object.keys(row).length > 0);
      const snapshot = {
        ...(tableData.snapshot ?? {}),
        rows,
        luckysheet: Array.isArray(luckysheetData) ? luckysheetData : luckysheetSheets,
      };
      lastLocalPersistAtRef.current = Date.now();
      if (convexEnabled && userId) {
        await updateTable({
          userId,
          tableId,
          snapshot,
          rows,
          schema: tableData.schema,
        });
      } else {
        await saveOnlineTable(tableId, {
          snapshot,
          rows,
          schema: tableData.schema,
        });
      }
      setHasPendingChanges(false);
      setLastSyncedAt(Date.now());
      window.dispatchEvent(new CustomEvent("online-table-saved", { detail: { tableId } }));
    } catch (error) {
      console.error("保存 Luckysheet 数据失败", error);
      setSaveError(reason === "close" ? "关闭前保存失败，请重试" : "自动保存失败");
    } finally {
      stopSavingHint();
      setIsSaving(false);
    }
  }, [convexEnabled, luckysheetSheets, startSavingHint, stopSavingHint, tableData, tableId, updateTable, userId]);

  const debouncedPersist = useDebouncedCallback(() => {
    void persistSnapshot("auto");
  }, 1200);

  useEffect(() => {
    persistSnapshotRef.current = persistSnapshot;
  }, [persistSnapshot]);

  useEffect(() => {
    return () => {
      debouncedPersist.cancel();
      void persistSnapshotRef.current?.("close");
      stopSavingHint();
    };
  }, [debouncedPersist, stopSavingHint]);

  useEffect(() => {
    if (!isLuckysheetReady) {
      lastPointerDownInGridRef.current = false;
      return;
    }
    const container = document.getElementById(LUCKY_SHEET_CONTAINER_ID);
    if (!container) {
      return;
    }
    const handlePointerDownInside = () => {
      lastPointerDownInGridRef.current = true;
    };
    const handlePointerDownDocument = (event: PointerEvent) => {
      if (!(event.target instanceof Node)) {
        return;
      }
      if (!container.contains(event.target)) {
        lastPointerDownInGridRef.current = false;
      }
    };
    container.addEventListener("pointerdown", handlePointerDownInside);
    document.addEventListener("pointerdown", handlePointerDownDocument);
    return () => {
      container.removeEventListener("pointerdown", handlePointerDownInside);
      document.removeEventListener("pointerdown", handlePointerDownDocument);
    };
  }, [isLuckysheetReady]);

  const focusLuckysheetEditor = useCallback(() => {
    const applyFocus = () => {
      const editor = document.getElementById("luckysheet-rich-text-editor");
      if (editor && typeof editor.focus === "function") {
        editor.focus();
        const selection = window.getSelection();
        if (selection && editor.childNodes.length > 0) {
          const range = document.createRange();
          range.selectNodeContents(editor);
          range.collapse(false);
          selection.removeAllRanges();
          selection.addRange(range);
        }
      }
    };
    requestAnimationFrame(() => {
      applyFocus();
      setTimeout(applyFocus, 0);
    });
  }, []);

  const shouldAutoFocusEditor = useCallback(
    (target: EventTarget | null) => {
      if (!isLuckysheetReady || !tableData) {
        return false;
      }
      const container = document.getElementById(LUCKY_SHEET_CONTAINER_ID);
      if (!container) {
        return false;
      }
      const editor = document.getElementById("luckysheet-rich-text-editor");
      if (!editor || document.activeElement === editor) {
        return false;
      }

      const targetElement = target instanceof HTMLElement ? target : null;
      if (isElementInsideEditorToolbar(targetElement)) {
        return false;
      }

      const activeElement = document.activeElement as HTMLElement | null;
      if (isElementInsideEditorToolbar(activeElement)) {
        return false;
      }

      if (targetElement && container.contains(targetElement)) {
        return true;
      }
      if (activeElement && container.contains(activeElement)) {
        return true;
      }
      return lastPointerDownInGridRef.current;
    },
    [isLuckysheetReady, tableData],
  );

  const ensureInlineEditor = useCallback(
    (target: EventTarget | null) => {
      if (!shouldAutoFocusEditor(target)) {
        return false;
      }
      if (isApplyingSnapshotRef.current) {
        return false;
      }
      if (!window.luckysheet || typeof window.luckysheet.enterEditMode !== "function") {
        return false;
      }
      window.luckysheet.enterEditMode();
      focusLuckysheetEditor();
      return true;
    },
    [focusLuckysheetEditor, shouldAutoFocusEditor],
  );

  useEffect(() => {
    if (!isLuckysheetReady) {
      return;
    }
    const handleKeydown = (event: KeyboardEvent) => {
      if (!isPrintableKey(event)) {
        return;
      }
      ensureInlineEditor(event.target);
    };
    const handleCompositionStart = (event: CompositionEvent) => {
      ensureInlineEditor(event.target);
    };
    window.addEventListener("keydown", handleKeydown, true);
    window.addEventListener("compositionstart", handleCompositionStart, true);
    return () => {
      window.removeEventListener("keydown", handleKeydown, true);
      window.removeEventListener("compositionstart", handleCompositionStart, true);
    };
  }, [ensureInlineEditor, isLuckysheetReady]);

  const isSingleCellSelection = useCallback((range: LuckysheetSelection[] | undefined) => {
    if (!Array.isArray(range) || range.length !== 1) {
      return false;
    }
    const target = range[0];
    if (!target) {
      return false;
    }
    const rowRange = target.row ?? (typeof target.row_focus === "number" ? [target.row_focus, target.row_focus] : undefined);
    const columnRange = target.column ?? (typeof target.column_focus === "number" ? [target.column_focus, target.column_focus] : undefined);
    if (!rowRange || !columnRange) {
      return false;
    }
    return rowRange[0] === rowRange[1] && columnRange[0] === columnRange[1];
  }, []);

  const tryEnterSingleClickEdit = useCallback(
    (range: LuckysheetSelection[] | undefined) => {
      if (!ENABLE_SINGLE_CLICK_EDIT) {
        return;
      }
      if (isApplyingSnapshotRef.current) {
        return;
      }
      if (typeof window === "undefined") {
        return;
      }
      const luckysheetInstance = window.luckysheet;
      if (!luckysheetInstance || typeof luckysheetInstance.enterEditMode !== "function") {
        return;
      }
      if (!isSingleCellSelection(range)) {
        return;
      }
    setTimeout(() => {
      const editor = document.getElementById("luckysheet-rich-text-editor");
      if (editor && document.activeElement === editor && isInlineEditorVisible()) {
        return;
      }
      luckysheetInstance.enterEditMode?.();
      focusLuckysheetEditor();
    }, 0);
    },
    [focusLuckysheetEditor, isSingleCellSelection],
  );

  useEffect(() => {
    if (!isLuckysheetReady) {
      return;
    }
    const container = document.getElementById(LUCKY_SHEET_CONTAINER_ID);
    if (!container) {
      return;
    }
    const handlePointerUp: EventListener = (event) => {
      const target = event.target instanceof Node ? event.target : null;
      if (target && !container.contains(target)) {
        return;
      }
      containerRef.current?.focus();
      requestAnimationFrame(() => {
        const selection = window.luckysheet?.getluckysheet_select_save?.();
        if (!selection) {
          return;
        }
        const normalized = Array.isArray(selection)
          ? (selection as LuckysheetSelection[])
          : [selection as LuckysheetSelection];
        tryEnterSingleClickEdit(normalized);
      });
    };
    const events = ["pointerup", "mouseup", "touchend"] as const;
    events.forEach((eventName) => {
      container.addEventListener(eventName, handlePointerUp, true);
    });
    return () => {
      events.forEach((eventName) => {
        container.removeEventListener(eventName, handlePointerUp, true);
      });
    };
  }, [isLuckysheetReady, tryEnterSingleClickEdit]);

  // Luckysheet 初始化和清理
  useEffect(() => {
    if (!isLuckysheetReady || !tableData || !containerRef.current || !window.luckysheet) {
      return;
    }

    if (hasInitializedRef.current && lastTableIdRef.current === tableId) {
      return;
    }

    hasInitializedRef.current = true;
    isApplyingSnapshotRef.current = true;

    if (containerRef.current.children.length > 0) {
      window.luckysheet?.destroy?.(LUCKY_SHEET_CONTAINER_ID);
      containerRef.current.innerHTML = "";
    }

    const gridKey = tableData?.grid_key ?? tableId;
    const loadUrl = gridKey ? `/api/luckysheet/load?gridKey=${gridKey}` : "";
    let canceled = false;
    let resizeRafId: number | null = null;
    const resizeTimerIds: number[] = [];
    let unlockTimerId: number | null = null;

    const safeResize = () => {
      if (canceled) return;
      const container = document.getElementById(LUCKY_SHEET_CONTAINER_ID);
      if (!container) return;
      const rect = container.getBoundingClientRect();
      if (rect.width < 10 || rect.height < 10) return;
      const instance = window.luckysheet as any;
      if (!instance || typeof instance.resize !== "function") return;
      try {
        instance.resize();
      } catch {
        // 忽略：Luckysheet 内部可能处于 destroy/create 过程中
      }
    };

    const scheduleResize = () => {
      if (canceled) return;
      resizeRafId = window.requestAnimationFrame(() => {
        safeResize();
      });
      // 多次兜底：避免首次打开时样式/布局尚未完全稳定
      resizeTimerIds.push(window.setTimeout(safeResize, 80));
      resizeTimerIds.push(window.setTimeout(safeResize, 240));
      resizeTimerIds.push(window.setTimeout(safeResize, 800));
    };

    const options = {
      container: LUCKY_SHEET_CONTAINER_ID,
      title: tableData.title ?? tableId,
      lang: "zh",
      showinfobar: false,
      showtoolbar: true,
      showsheetbar: true,
      showstatisticBar: true,
      allowEdit: true,
      row: DEFAULT_TABLE_ROWS,
      column: DEFAULT_TABLE_COLUMNS,
      data: normalizedSheets,
      allowUpdate: false,
      gridKey,
      loadUrl,
      pointEdit: true,
      pointEditZoom: typeof window !== "undefined" && window.devicePixelRatio ? window.devicePixelRatio : 1,
      uploadImage: async (file: File) => {
        const formData = new FormData();
        formData.append("image", file);
        const response = await fetch("/api/luckysheet/upload-image", {
          method: "POST",
          body: formData,
        });
        const payload = await response.json().catch(() => null);
        if (!response.ok || !payload?.url) {
          throw new Error(payload?.msg ?? "上传图片失败");
        }
        return payload.url as string;
      },
      imageUrlHandle: (url: string) => url,
      hook: {
        workbookCreateAfter: () => {
          if (canceled) return;
          setIsTableLoading(false);
          // 仅在 Luckysheet 完成 DOM 构建后再调用 resize，避免触发其内部空引用（offsetHeight of null）
          scheduleResize();
        },
        updated: () => {
          if (isApplyingSnapshotRef.current) return;
          setHasPendingChanges(true);
          debouncedPersist();
        },
        cellEditBefore: () => {
          focusLuckysheetEditor();
        },
        rangeSelect: (_sheet: unknown, selectedRange: LuckysheetSelection[] | LuckysheetSelection | undefined) => {
          const normalizedRange = Array.isArray(selectedRange)
            ? (selectedRange as LuckysheetSelection[])
            : selectedRange
              ? [selectedRange]
              : undefined;
          focusLuckysheetEditor();
          tryEnterSingleClickEdit(normalizedRange);
        },
        rangeMoveAfter: (_oldRange: LuckysheetSelection[] | undefined, newRange: LuckysheetSelection[] | undefined) => {
          focusLuckysheetEditor();
          tryEnterSingleClickEdit(newRange);
        },
      },
    };

    if (process.env.NODE_ENV !== "production") {
       
      console.log("[FullScreenTableEditor] init luckysheet", { tableId, sheets: options.data });
    }
    try {
      window.luckysheet?.create?.(options as any);
    } catch (error) {
      console.error("Luckysheet 初始化失败", error);
      setTableError("Luckysheet 初始化失败，请重试");
      isApplyingSnapshotRef.current = false;
      return;
    }

    // 等待首帧渲染完成再开放 updated 事件
    unlockTimerId = window.setTimeout(() => {
      isApplyingSnapshotRef.current = false;
    }, 0);

    const containerEl = containerRef.current;
    return () => {
      canceled = true;
      if (resizeRafId !== null) {
        cancelAnimationFrame(resizeRafId);
      }
      resizeTimerIds.forEach((id) => clearTimeout(id));
      if (unlockTimerId !== null) {
        clearTimeout(unlockTimerId);
      }
      if (window.luckysheet) {
        window.luckysheet?.destroy?.(LUCKY_SHEET_CONTAINER_ID);
      }
      if (containerEl) {
        containerEl.innerHTML = "";
      }
      hasInitializedRef.current = false;
    };
  }, [debouncedPersist, normalizedSheets, isLuckysheetReady, tableData, tableId, focusLuckysheetEditor, tryEnterSingleClickEdit]);

  const handleClose = async () => {
    await persistSnapshot("close");
    onClose();
  };

  const showLoadingOverlay = !isLuckysheetReady || isTableLoading;
  const loadingMessage = !isLuckysheetReady ? "正在加载 Luckysheet 资源..." : "正在加载表格数据...";

  const handleRenameSubmit = useCallback(async () => {
    if (!tableData) {
      setIsRenaming(false);
      return;
    }
    const nextTitle = (renameValue || "").trim() || "未命名表格";
    if (nextTitle === tableData.title) {
      setIsRenaming(false);
      return;
    }
    setIsSavingTitle(true);
    try {
      let finalTitle = nextTitle;
      if (convexEnabled && userId) {
        await updateTable({ userId, tableId, title: nextTitle });
      } else {
        const updated = await saveOnlineTable(tableId, { title: nextTitle });
        finalTitle = updated.title ?? nextTitle;
      }
      setTableData((prev) => (prev ? { ...prev, title: finalTitle } : prev));
      window.dispatchEvent(new CustomEvent("online-table-saved", { detail: { tableId } }));
    } catch (error) {
      console.error("重命名表格失败", error);
      setRenameValue(tableData.title ?? "");
    } finally {
      setIsRenaming(false);
      setIsSavingTitle(false);
    }
  }, [convexEnabled, renameValue, tableData, tableId, updateTable, userId]);

  const statusText = saveError
    ? saveError
    : isSaving && showSavingHint
      ? "同步中..."
      : hasPendingChanges
        ? "有未保存变更"
        : lastSyncedAt
          ? `已同步 ${new Date(lastSyncedAt).toLocaleTimeString()}`
          : "准备就绪";

  return (
    <div className="fixed inset-0 z-50 bg-white dark:bg-gray-900 flex flex-col">
      {/* 顶部工具栏 */}
      <header className="flex justify-between items-center p-3 border-b border-gray-200 shadow-sm">
        <div className="flex items-center space-x-3">
          <Table className="h-5 w-5 text-blue-500" />
          {isRenaming ? (
            <input
              autoFocus
              className="w-64 rounded border border-gray-200 px-2 py-1 text-lg font-semibold text-gray-800 focus:border-emerald-500 focus:outline-none"
              value={renameValue}
              onChange={(e) => setRenameValue(e.target.value)}
              onBlur={handleRenameSubmit}
              onKeyDown={(e) => {
                if (e.key === "Enter") {
                  e.preventDefault();
                  void handleRenameSubmit();
                }
                if (e.key === "Escape") {
                  e.preventDefault();
                  setRenameValue(tableData?.title ?? "");
                  setIsRenaming(false);
                }
              }}
            />
          ) : (
            <button
              type="button"
              className="flex items-center gap-2 text-left text-lg font-bold text-gray-900 hover:text-emerald-600"
              onClick={() => setIsRenaming(true)}
              title="点击重命名表格"
            >
              <span className="truncate max-w-xs">
                在线表格编辑 - {(tableData?.title ?? tableId).slice(0, 24)}
              </span>
              {isSavingTitle && <Loader2 className="h-4 w-4 animate-spin text-gray-400" />}
            </button>
          )}
          <Zap className="h-4 w-4 text-yellow-500" />
          <span className="text-xs text-yellow-600 font-medium" title="协同模式">协同模式 (单用户模式)</span>
        </div>
        <div className="flex items-center space-x-3">
          <span className="text-xs text-gray-500">{statusText}</span>
          <button
            onClick={handleClose}
            className="p-2 rounded-full hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
            title="退出并保存"
          >
            {isSaving ? <Loader2 className="h-5 w-5 animate-spin" /> : <X className="h-5 w-5" />}
          </button>
        </div>
      </header>
      
      <div className="relative flex-grow w-full">
        {/* Luckysheet 容器（始终占位，避免 create 时容器不可见导致布局计算错误） */}
        <div
          id={LUCKY_SHEET_CONTAINER_ID}
          ref={containerRef}
          className="h-full w-full"
          tabIndex={-1}
          aria-label="在线表格全屏编辑区域"
        />

        {showLoadingOverlay && (
          <div className="absolute inset-0 flex justify-center items-center text-gray-500 bg-white/90 dark:bg-gray-900/90">
            <p>{loadingMessage}</p>
          </div>
        )}

        {tableError && !showLoadingOverlay && (
          <div className="absolute inset-0 flex flex-col justify-center items-center text-red-500 bg-white/95 dark:bg-gray-900/95 space-y-2">
            <p>{tableError}</p>
            <button
              type="button"
              className="px-3 py-1 rounded-md border border-red-300 text-sm"
              onClick={() => fetchTable(tableId)}
            >
              重试
            </button>
          </div>
        )}
      </div>
    </div>
  );
};

export default FullScreenTableEditor;
