import React, { memo, useEffect, useRef, useLayoutEffect, useState, useCallback, useMemo } from 'react';
import { isFormula, extractFormula, calculateFormula, formatNumber } from '../../utils/formulaUtils';
import { saveToStorage, loadFromStorage } from '../../utils/localStorageUtils';
import { useRealtime } from '../../contexts/RealtimeContext';

const EDITOR_STYLES = {
  position: 'absolute',
  zIndex: 12,
  top: 0,
};

const FORMULA_INDICATOR_STYLES = {
  position: 'absolute',
  top: '-20px',
  left: '4px',
  fontSize: '10px',
  color: '#666',
  background: '#f0f0f0',
  padding: '2px 6px',
  borderRadius: '3px',
  pointerEvents: 'none',
};

const TEXTAREA_STYLES = {
  width: '100%',
  height: '3rem',
  fieldSizing: 'content',
  fontSize: 'inherit',
};

const EditCell = memo(({ refCell, onChange, disabled, value, tableId, cellId, table }) => {
  const { endEditing: contextEndEditing } = useRealtime();
  const storageKey = `formula_${tableId}_${cellId}`;

  const [state, setState] = useState(() => ({
    currentValue: value,
    displayValue: value,
    isFormulaMode: false,
  }));

  // Позиция ячейки
  const [position, setPosition] = useState();
  const textareaRef = useRef(null);

  const refFinished = useRef(false);

  // Загрузка сохраненной формулы
  useEffect(() => {
    const savedFormula = loadFromStorage(storageKey);
    if (savedFormula && isFormula(savedFormula)) {
      try {
        const formula = extractFormula(savedFormula);
        const result = calculateFormula(formula);
        setState({
          currentValue: savedFormula,
          displayValue: formatNumber(result),
          isFormulaMode: true,
        });
      } catch {
        setState({
          currentValue: savedFormula,
          displayValue: '#ОШИБКА',
          isFormulaMode: true,
        });
      }
    }
  }, [storageKey]);

  // Вычисление позиции
  useLayoutEffect(() => {
    if (!refCell?.current) return;

    const td = refCell.current.offsetParent;
    const tr = td?.offsetParent;

    if (td && tr) {
      setPosition({
        left: td.offsetLeft,
        width: td.offsetWidth,
        translateY: tr.style.transform || '',
      });
    }
  }, [refCell]);

  // Auto-resize
  useLayoutEffect(() => {
    const el = textareaRef.current;
    if (!el) return;

    const resize = () => {
      el.style.minHeight = '3rem';
      el.style.height = '3rem';
      el.style.height = el.scrollHeight + 'px';
      el.style.maxHeight = '180px';
    };

    resize();
    const observer = new ResizeObserver(resize);
    observer.observe(el);

    return () => observer.disconnect();
  }, [state.currentValue]);

  useEffect(() => {
    // Небольшая задержка для гарантии, что DOM полностью готов
    const timeoutId = setTimeout(() => {
      if (textareaRef.current && !disabled) {
        textareaRef.current.focus();
        textareaRef.current.select();
      }
    }, 50);

    return () => clearTimeout(timeoutId);
  }, [disabled]);

  const handleSave = useCallback(() => {
    const { currentValue } = state;

    if (isFormula(currentValue)) {
      saveToStorage(storageKey, currentValue);
      try {
        const formula = extractFormula(currentValue);
        const result = calculateFormula(formula);
        const formattedResult = formatNumber(result);
        setState(prev => ({
          ...prev,
          displayValue: formattedResult,
          isFormulaMode: true,
        }));
        onChange?.(formattedResult);
      } catch {
        setState(prev => ({
          ...prev,
          displayValue: '#ОШИБКА',
          isFormulaMode: true,
        }));
        onChange?.(currentValue);
      }
    } else {
      localStorage.removeItem(storageKey);
      setState(prev => ({
        ...prev,
        displayValue: currentValue,
        isFormulaMode: false,
      }));
      onChange?.(currentValue);
    }
  }, [state, storageKey, onChange]);

  const finishEditing = useCallback(() => {
    if (refFinished.current) return;
    refFinished.current = true;
    if (!disabled) {
      handleSave();
    }
    const editingCell = table.getState().editingCell;
    if (editingCell) {
      contextEndEditing?.(editingCell.row, editingCell.column);
    }
  }, [disabled, handleSave, table, contextEndEditing]);

  useEffect(() => {
    const handleClickOutside = (event) => {
      const el = textareaRef.current;
      if (el && !el.contains(event.target)) {
        finishEditing();
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, [finishEditing]);

  const handleChange = useCallback((e) => {
    const value = e.target.value;
    setState(prev => ({
      ...prev,
      currentValue: value,
      displayValue: value,
    }));
  }, []);

  const handleKeyDown = useCallback((e) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      finishEditing();
    }
  }, [finishEditing]);

  const editorStyles = useMemo(() => ({
    ...EDITOR_STYLES,
    left: position?.left || 0,
    width: position?.width || 0,
    transform: position?.translateY || 0,
  }), [position]);

  const textareaStyles = useMemo(() => ({
    ...TEXTAREA_STYLES,
    backgroundColor: state.isFormulaMode ? '#f8f9fa' : 'white',
    border: state.isFormulaMode ? '2px solid #4a90d9' : undefined,
  }), [state.isFormulaMode]);

  return (
    <tr>
      <td>
        {position &&
          <div style={editorStyles}>
            {state.isFormulaMode && (
              <div style={FORMULA_INDICATOR_STYLES}>fx</div>
            )}
            <textarea
              ref={textareaRef}
              disabled={disabled}
              style={textareaStyles}
              onChange={handleChange}
              value={state.currentValue}
              onKeyDown={handleKeyDown}
              placeholder={state.isFormulaMode ? 'Введите формулу (начинается с =)' : ''}
            />
          </div>
        }

      </td>
    </tr>
  );
});

EditCell.displayName = 'EditCell';

export default EditCell;