import { useState, useEffect, useRef, useCallback } from "@wordpress/element";
import { detectActiveFormats, availableFormats } from "./formats";

/**
 * useInlineToolbar - インラインツールバー管理用のカスタムフック
 * 新しいフォーマット構成に対応
 *
 * @param {Object} options
 * @param {boolean} options.isSelected - ブロックが選択されているか
 * @param {RefObject} options.editorRef - エディタ要素のref
 * @param {Array} options.enabledFormats - 有効なフォーマットの配列
 * @returns {Object} ツールバーの状態と制御関数
 */
export const useInlineToolbar = ({ isSelected, editorRef, enabledFormats = ["bold", "italic"] } = {}) => {
  const [showToolbar, setShowToolbar] = useState(false);
  const [toolbarPosition, setToolbarPosition] = useState({ x: 0, y: 0 });
  const [selectedText, setSelectedText] = useState("");
  const [currentRange, setCurrentRange] = useState(null);
  const [activeFormats, setActiveFormats] = useState({});

  // 選択範囲の更新
  const updateSelection = useCallback(() => {
    const selection = window.getSelection();

    if (!selection.rangeCount || selection.isCollapsed) {
      setShowToolbar(false);
      return;
    }

    const range = selection.getRangeAt(0);

    // エディタ要素内の選択かを確認
    if (editorRef?.current) {
      let isWithinEditor = false;
      try {
        isWithinEditor = editorRef.current.contains(range.commonAncestorContainer) || editorRef.current.contains(range.startContainer) || editorRef.current.contains(range.endContainer);
      } catch (e) {
        // DOM階層の問題でエラーが発生した場合は選択位置をチェック
        const rect = range.getBoundingClientRect();
        const editorRect = editorRef.current.getBoundingClientRect();
        isWithinEditor = rect.left >= editorRect.left && rect.right <= editorRect.right && rect.top >= editorRect.top && rect.bottom <= editorRect.bottom;
      }

      if (!isWithinEditor) {
        setShowToolbar(false);
        return;
      }
    }

    const rect = range.getBoundingClientRect();

    if (rect.width > 0) {
      // より確実な選択範囲の保存
      const clonedRange = range.cloneRange();
      // console.log('選択範囲を保存:', {
      //   text: selection.toString(),
      //   startOffset: clonedRange.startOffset,
      //   endOffset: clonedRange.endOffset,
      //   startContainer: clonedRange.startContainer.nodeName,
      //   endContainer: clonedRange.endContainer.nodeName
      // });

      setCurrentRange(clonedRange);

      // ツールバーの位置を設定
      const position = {
        x: rect.left + rect.width / 2,
        y: rect.top + window.scrollY - 50,
      };
      setToolbarPosition(position);
      setSelectedText(selection.toString());

      // アクティブなフォーマットを検出
      updateActiveFormats(range);

      setShowToolbar(true);
    }
  }, [editorRef]);

  // アクティブなフォーマットを検出（新しいフォーマット構成使用）
  const updateActiveFormats = useCallback((range) => {
    // 新しいフォーマット検出システムを使用
    const formats = detectActiveFormats(range);
    setActiveFormats(formats);
  }, []);

  // パレット操作の相互作用参照
  const paletteInteractionRef = useRef(false);

  // カラーピッカーアクティブ状態の検出関数（強化版）
  const isColorPickerActive = useCallback(() => {
    // 既存のセレクタに加えて、新たな検出条件を追加
    const selectors = [
      ".components-color-palette-popover",
      ".components-color-picker",
      ".components-color-palette-wrapper",
      ".components-color-palette",
      'input[type="color"]:focus',
      'input[data-color-picker-active="true"]',
      '[data-color-picker-open="true"]',
    ];

    // DOM要素による検出
    const hasColorPickerElement = selectors.some((selector) => document.querySelector(selector));

    // パレット操作フラグによる検出
    const isPaletteInteracting = paletteInteractionRef.current;

    // フォーカス中のテキスト入力がカラーコード形式かチェック
    const activeElement = document.activeElement;
    const isColorCodeInput = activeElement && activeElement.type === "text" && activeElement.placeholder === "#e63946";

    // カラーピッカーのネイティブダイアログが開いているかチェック
    const colorInputActive = document.querySelector('input[type="color"][data-color-picker-active="true"]');

    return hasColorPickerElement || isPaletteInteracting || isColorCodeInput || colorInputActive;
  }, []);

  // デバウンス処理付きの選択変更ハンドラ
  const debouncedSelectionHandler = useRef(null);

  // イベントリスナーの設定
  useEffect(() => {
    const handleSelectionChange = () => {
      // カラーピッカーがアクティブな場合は選択変更を無視
      if (isColorPickerActive()) {
        return;
      }

      // 既存のデバウンス処理をクリア
      if (debouncedSelectionHandler.current) {
        clearTimeout(debouncedSelectionHandler.current);
      }

      // 50msのデバウンス処理を適用
      debouncedSelectionHandler.current = setTimeout(() => {
        // エディタがフォーカスされているかを確認
        const selection = window.getSelection();
        const isEditorFocused = editorRef?.current && editorRef.current.contains && editorRef.current.contains(selection.focusNode);

        if (isSelected || isEditorFocused) {
          updateSelection();
        } else {
          setShowToolbar(false);
        }
      }, 50);
    };

    // イベントリスナーを登録
    document.addEventListener("selectionchange", handleSelectionChange);
    document.addEventListener("mouseup", handleSelectionChange);
    document.addEventListener("mousedown", handleSelectionChange);
    document.addEventListener("keyup", handleSelectionChange);

    return () => {
      // クリーンアップ時にデバウンス処理もクリア
      if (debouncedSelectionHandler.current) {
        clearTimeout(debouncedSelectionHandler.current);
      }

      document.removeEventListener("selectionchange", handleSelectionChange);
      document.removeEventListener("mouseup", handleSelectionChange);
      document.removeEventListener("mousedown", handleSelectionChange);
      document.removeEventListener("keyup", handleSelectionChange);
    };
  }, [isSelected, updateSelection, editorRef, isColorPickerActive]);

  // 選択範囲を復元する関数
  const restoreSelection = useCallback(() => {
    if (currentRange) {
      const selection = window.getSelection();
      selection.removeAllRanges();
      selection.addRange(currentRange);

      // エディタにフォーカスを戻す
      if (editorRef?.current) {
        editorRef.current.focus();
      }
    }
  }, [currentRange, editorRef]);

  // フォーマットを適用する汎用関数（新しいフォーマット構成使用）
  const applyFormat = useCallback(
    (formatKey, additionalParams = null) => {
      const format = availableFormats[formatKey];
      if (!format || !currentRange) return;

      // 新しいフォーマット適用システムを使用
      // ハイライト機能の場合は追加パラメータ（色）を渡す
      if (formatKey === "highlight" && additionalParams) {
        format.apply(editorRef, currentRange, additionalParams);
      } else {
        format.apply(editorRef, currentRange);
      }
      setShowToolbar(false);
    },
    [editorRef, currentRange],
  );

  // 有効なフォーマットに基づいて適用関数を動的に生成
  const formatAppliers = useCallback(() => {
    const appliers = {};
    enabledFormats.forEach((formatKey) => {
      if (availableFormats[formatKey]) {
        appliers[`apply${formatKey.charAt(0).toUpperCase() + formatKey.slice(1)}`] = () => applyFormat(formatKey);
      }
    });
    return appliers;
  }, [enabledFormats, applyFormat]);

  return {
    // 状態
    showToolbar,
    toolbarPosition,
    selectedText,
    activeFormats,
    currentRange,

    // 制御関数
    setShowToolbar,
    updateSelection,
    restoreSelection,
    applyFormat,

    // カラーピッカー関連
    paletteInteractionRef,
    isColorPickerActive,

    // 動的に生成されたフォーマット適用関数
    ...formatAppliers(),

    // 下位互換性のための直接関数
    applyBold: () => applyFormat("bold"),
    applyItalic: () => applyFormat("italic"),
    applyHighlight: () => applyFormat("highlight"),
    applyLink: () => applyFormat("link"),
  };
};

export default useInlineToolbar;
