import React, { useEffect, useRef, useState } from "react";
import { Icon } from "@iconify/react";

interface FloatingToolbarProps {
  textareaRef: React.RefObject<HTMLTextAreaElement>;
  onFormat: (before: string, after: string) => void;
  visible: boolean;
  position: { top: number; left: number };
  onHide?: () => void;
  onInsertColor?: () => void;
  activeFormats?: {
    bold?: boolean;
    italic?: boolean;
    strikethrough?: boolean;
  };
  hasSelection?: boolean; // Есть ли выделение текста
}

export const FloatingToolbar: React.FC<FloatingToolbarProps> = ({
  textareaRef,
  onFormat,
  visible,
  position,
  onHide,
  onInsertColor,
  activeFormats = {},
  hasSelection = false,
}) => {
  const toolbarRef = useRef<HTMLDivElement>(null);
  const [isDragging, setIsDragging] = useState(false);
  const [startX, setStartX] = useState(0);
  const [scrollLeft, setScrollLeft] = useState(0);

  useEffect(() => {
    if (visible && toolbarRef.current) {
      // Небольшая задержка для корректного расчета размеров после рендера
      setTimeout(() => {
        if (!toolbarRef.current) return;
        
        const toolbar = toolbarRef.current;
        const rect = toolbar.getBoundingClientRect();
        const windowWidth = window.innerWidth;
        const windowHeight = window.innerHeight;
        const padding = 10;

        // Получаем внутренний контейнер с кнопками для определения реальной ширины
        const toolbarContent = toolbar.querySelector('.floating-toolbar') as HTMLElement;
        const toolbarContentWidth = toolbarContent ? toolbarContent.scrollWidth : rect.width;
        const availableWidth = windowWidth - padding * 2;

        let top = position.top - rect.height - padding;
        let left = position.left;

        // Если контент шире доступного пространства, устанавливаем maxWidth для wrapper
        if (toolbarContentWidth > availableWidth) {
          toolbar.style.maxWidth = `${availableWidth}px`;
        }

        // Если toolbar выходит за правую границу экрана
        if (left + rect.width > windowWidth - padding) {
          // Если контент шире экрана, используем прокрутку и позиционируем по левому краю
          if (toolbarContentWidth > availableWidth) {
            left = padding;
          } else {
            // Иначе выравниваем по правому краю
            left = Math.max(padding, windowWidth - rect.width - padding);
          }
        }

        // Если toolbar выходит за левую границу экрана
        if (left < padding) {
          left = padding;
        }

        // Если toolbar выходит за верхнюю границу экрана
        if (top < padding) {
          top = position.top + 30; // Показываем снизу от выделения
        }

        // Проверяем нижнюю границу
        if (top + rect.height > windowHeight - padding) {
          top = windowHeight - rect.height - padding;
        }

        toolbar.style.top = `${top}px`;
        toolbar.style.left = `${left}px`;
      }, 0);
    }
  }, [visible, position]);


  const handleMouseDown = (e: React.MouseEvent) => {
    // Не начинаем перетаскивание если кликнули на кнопку
    if ((e.target as HTMLElement).closest('.floating-toolbar-btn')) return;

    if (!toolbarRef.current) return;
    setIsDragging(true);
    setStartX(e.pageX - toolbarRef.current.offsetLeft);
    setScrollLeft(toolbarRef.current.scrollLeft);
  };

  const handleMouseMove = (e: MouseEvent) => {
    if (!isDragging || !toolbarRef.current) return;
    e.preventDefault();
    const x = e.pageX - toolbarRef.current.offsetLeft;
    const walk = (x - startX) * 2; // Увеличиваем скорость прокрутки
    toolbarRef.current.scrollLeft = scrollLeft - walk;
  };

  const handleMouseUp = () => {
    setIsDragging(false);
  };

  // Обработчики для document чтобы отслеживать mouseMove и mouseUp даже вне элемента
  useEffect(() => {
    if (isDragging) {
      document.addEventListener('mousemove', handleMouseMove);
      document.addEventListener('mouseup', handleMouseUp);
    } else {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    }

    return () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };
  }, [isDragging]);

  const handleFormat = (before: string, after: string) => {
    onFormat(before, after);
    // Не скрываем toolbar - оставляем его видимым для дальнейших действий
    setTimeout(() => {
      if (textareaRef.current) {
        textareaRef.current.focus();
        // Обновляем выделение после применения форматирования
        const start = textareaRef.current.selectionStart;
        const end = textareaRef.current.selectionEnd;
        if (start !== end) {
          textareaRef.current.setSelectionRange(start, end);
        }
      }
    }, 0);
  };

  const handleCopy = async () => {
    const textarea = textareaRef.current;
    if (!textarea) return;

    const start = textarea.selectionStart;
    const end = textarea.selectionEnd;
    
    if (start === end) return; // Нет выделения

    const selectedText = textarea.value.substring(start, end);
    
    try {
      await navigator.clipboard.writeText(selectedText);
      // Можно добавить уведомление об успешном копировании
    } catch (err) {
      // Fallback для старых браузеров
      const textArea = document.createElement("textarea");
      textArea.value = selectedText;
      textArea.style.position = "fixed";
      textArea.style.left = "-999999px";
      document.body.appendChild(textArea);
      textArea.select();
      document.execCommand("copy");
      document.body.removeChild(textArea);
    }
  };

  const handleCut = async () => {
    const textarea = textareaRef.current;
    if (!textarea) return;

    const start = textarea.selectionStart;
    const end = textarea.selectionEnd;
    
    if (start === end) return; // Нет выделения

    const selectedText = textarea.value.substring(start, end);
    
    try {
      await navigator.clipboard.writeText(selectedText);
    } catch (err) {
      // Fallback для старых браузеров
      const textArea = document.createElement("textarea");
      textArea.value = selectedText;
      textArea.style.position = "fixed";
      textArea.style.left = "-999999px";
      document.body.appendChild(textArea);
      textArea.select();
      document.execCommand("copy");
      document.body.removeChild(textArea);
    }
    
    // Удаляем выделенный текст
    const newValue = textarea.value.substring(0, start) + textarea.value.substring(end);
    
    // Обновляем значение через React-совместимое событие
    const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
      window.HTMLTextAreaElement.prototype,
      "value"
    )?.set;
    
    if (nativeInputValueSetter) {
      nativeInputValueSetter.call(textarea, newValue);
      const inputEvent = new Event("input", { bubbles: true });
      textarea.dispatchEvent(inputEvent);
    } else {
      textarea.value = newValue;
      const inputEvent = new Event("input", { bubbles: true });
      textarea.dispatchEvent(inputEvent);
    }
    
    textarea.setSelectionRange(start, start);
    textarea.focus();
  };

  const handlePaste = async () => {
    const textarea = textareaRef.current;
    if (!textarea) return;

    const start = textarea.selectionStart;
    const end = textarea.selectionEnd;

    try {
      const text = await navigator.clipboard.readText();
      
      // Вставляем текст в позицию курсора или заменяем выделенный текст
      const newValue = 
        textarea.value.substring(0, start) + 
        text + 
        textarea.value.substring(end);
      
      // Обновляем значение через React-совместимое событие
      const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
        window.HTMLTextAreaElement.prototype,
        "value"
      )?.set;
      
      if (nativeInputValueSetter) {
        nativeInputValueSetter.call(textarea, newValue);
        const inputEvent = new Event("input", { bubbles: true });
        textarea.dispatchEvent(inputEvent);
      } else {
        textarea.value = newValue;
        const inputEvent = new Event("input", { bubbles: true });
        textarea.dispatchEvent(inputEvent);
      }
      
      // Устанавливаем курсор после вставленного текста
      const newCursorPos = start + text.length;
      textarea.setSelectionRange(newCursorPos, newCursorPos);
      textarea.focus();
    } catch (err) {
      // Fallback: используем execCommand для вставки
      textarea.focus();
      document.execCommand("paste");
    }
  };

  // Не показываем toolbar, если он не видим или нет выделения текста
  if (!visible || !hasSelection) return null;

  return (
    <div
      ref={toolbarRef}
      className="floating-toolbar-wrapper"
      style={{
        position: "fixed",
        top: `${position.top}px`,
        left: `${position.left}px`,
        zIndex: 1000,
        cursor: isDragging ? 'grabbing' : (toolbarRef.current && toolbarRef.current.scrollWidth > toolbarRef.current.clientWidth ? 'grab' : 'default'),
      }}
      onMouseDown={(e) => {
        // Предотвращаем потерю выделения при клике на toolbar
        e.preventDefault();
        handleMouseDown(e);
      }}
      onContextMenu={(e) => {
        // Предотвращаем появление контекстного меню браузера на toolbar
        e.preventDefault();
      }}
    >
      <div className="floating-toolbar">
        <button
          className="floating-toolbar-btn"
          onClick={onHide}
          title="Закрыть"
        >
          <Icon icon="mdi:close" />
        </button>

      {hasSelection && (
        <>
          <button
            className="floating-toolbar-btn"
            onClick={handleCopy}
            title="Копировать"
          >
            <Icon icon="mdi:content-copy" />
          </button>
          <button
            className="floating-toolbar-btn"
            onClick={handleCut}
            title="Вырезать"
          >
            <Icon icon="mdi:content-cut" />
          </button>
          <button
            className="floating-toolbar-btn"
            onClick={handlePaste}
            title="Вставить"
          >
            <Icon icon="mdi:content-paste" />
          </button>
        </>
      )}

      {hasSelection && (
        <>
          <div className="floating-toolbar-separator" />

          <button
            className={`floating-toolbar-btn ${activeFormats.bold ? "active" : ""}`}
            onClick={() => handleFormat("**", "**")}
            title="Жирный"
          >
            <Icon icon="mdi:format-bold" />
          </button>
          <button
            className={`floating-toolbar-btn ${
              activeFormats.italic ? "active" : ""
            }`}
            onClick={() => handleFormat("*", "*")}
            title="Курсив"
          >
            <Icon icon="mdi:format-italic" />
          </button>
          <button
            className={`floating-toolbar-btn ${
              activeFormats.strikethrough ? "active" : ""
            }`}
            onClick={() => handleFormat("~~", "~~")}
            title="Зачеркнутый"
          >
            <Icon icon="mdi:format-strikethrough" />
          </button>

          <div className="floating-toolbar-separator" />

          <button
            className="floating-toolbar-btn"
            onClick={() => onInsertColor?.()}
            title="Цвет текста"
          >
            <Icon icon="mdi:palette" />
          </button>

          <button
            className="floating-toolbar-btn"
            onClick={() => handleFormat("||", "||")}
            title="Скрытый текст"
          >
            <Icon icon="mdi:eye-off" />
          </button>

          <button
            className="floating-toolbar-btn"
            onClick={() => handleFormat("`", "`")}
            title="Код"
          >
            <Icon icon="mdi:code-tags" />
          </button>

          <button
            className="floating-toolbar-btn"
            onClick={() => handleFormat("> ", "")}
            title="Цитата"
          >
            <Icon icon="mdi:format-quote-close" />
          </button>
        </>
      )}
      </div>
    </div>
  );
};
