import { CSSProperties, memo, useCallback } from 'react'
import { CellProps, ROW_HEIGHT } from '../types'

export const Cell = memo(
  ({
    sheetType,
    rowIndex,
    colIndex,
    columnWidth,
    columnWidths,
    isSelected,
    isInMultiSelection,
    multiSelectionActive,
    isEditing,
    displayValue,
    rawValue,
    isModified,
    availablePx,
    onCellClick,
    onCellDoubleClick,
    onCellValueChange,
    onCellReferenceClick,
    onCellMouseDown,
    onCellMouseEnter,
    onCellMouseUp,
    isInEditMode,
    stopEditing,
    setActiveSheet,
    activeCellRef,
    style,
    mergedCellInfo,
    highlightColor,
    isCopied,
    isCut,
  }: CellProps) => {
    // Если ячейка объединена, но не является основной, не рендерим её
    if (mergedCellInfo?.isMerged && !mergedCellInfo.isMainCell) {
      return null
    }

    // Определяем стили ячейки
    const getCellStyles = (): { className: string; style: CSSProperties } => {
      let className = 'border border-border'
      let cellStyle: CSSProperties = {
        ...style,
        overflow: 'visible',
        padding: 0,
        userSelect: 'none',
      }

      // Подсветка формул имеет приоритет
      if (highlightColor) {
        className += ` ${highlightColor}`
      } else if (isModified && !mergedCellInfo?.isMerged) {
        className += ' bg-yellow-200'
      }

      // Множественное выделение
      if (isInMultiSelection) {
        cellStyle.backgroundColor = 'rgba(59,130,246,0.08)'
      }

      // Стили для скопированных/вырезанных ячеек
      if (isCopied || isCut) {
        cellStyle.border = '2px dashed hsl(var(--primary))'
        cellStyle.backgroundColor = isCut
          ? 'rgba(239, 68, 68, 0.1)'
          : 'rgba(34, 197, 94, 0.1)'
      }

      // Объединенные ячейки
      if (
        mergedCellInfo?.isMainCell &&
        mergedCellInfo.rowSpan &&
        mergedCellInfo.colSpan
      ) {
        const { rowSpan, colSpan } = mergedCellInfo

        // Рассчитываем размеры объединенной ячейки
        const totalWidth = columnWidths
          .slice(colIndex, colIndex + colSpan)
          .reduce((sum, width) => sum + width, 0)
        const totalHeight = ROW_HEIGHT * rowSpan

        // Определяем фон
        let backgroundColor = 'white'
        if (highlightColor) {
          const bgMatch = highlightColor.match(/bg-(\w+)-(\d+)/)
          if (bgMatch) {
            backgroundColor = `var(--${bgMatch[1]}-${bgMatch[2]})`
          }
        } else if (isSelected) {
          backgroundColor = 'hsl(var(--accent))'
        } else if (isModified) {
          backgroundColor = '#fef08a'
        }

        cellStyle = {
          ...cellStyle,
          width: totalWidth,
          height: totalHeight,
          zIndex: 10,
          backgroundColor,
        }
      }

      return { className, style: cellStyle }
    }

    const { className, style: cellStyle } = getCellStyles()

    const handleClick = useCallback(
      (e: React.MouseEvent) => {
        if (isInEditMode) {
          e.preventDefault()
          e.stopPropagation()
          return
        }
        onCellClick(rowIndex, colIndex, e)
      },
      [isInEditMode, onCellClick, rowIndex, colIndex]
    )

    const handleDoubleClick = useCallback(
      () => onCellDoubleClick(rowIndex, colIndex),
      [onCellDoubleClick, rowIndex, colIndex]
    )

    const handleMouseDown = useCallback(
      (e: React.MouseEvent) => {
        if (!isInEditMode) {
          e.preventDefault()
        }

        // Вставка ссылки в режиме редактирования
        if (isInEditMode && onCellReferenceClick && !isSelected) {
          e.preventDefault()
          e.stopPropagation()
          onCellReferenceClick(sheetType, rowIndex, colIndex)
          return
        }

        // Drag selection
        if (onCellMouseDown) {
          setActiveSheet(sheetType)
          onCellMouseDown(rowIndex, colIndex, e)
        }
      },
      [
        isInEditMode,
        onCellReferenceClick,
        isSelected,
        sheetType,
        rowIndex,
        colIndex,
        onCellMouseDown,
        setActiveSheet,
      ]
    )

    const handleMouseEnter = useCallback(() => {
      onCellMouseEnter?.(rowIndex, colIndex)
    }, [onCellMouseEnter, rowIndex, colIndex])

    const handleMouseUp = useCallback(() => {
      onCellMouseUp?.()
    }, [onCellMouseUp])

    const handleInputBlur = useCallback(
      (e: React.FocusEvent) => {
        const relatedTarget = e.relatedTarget as HTMLElement
        if (relatedTarget?.closest('.formula-bar')) {
          return
        }
        stopEditing(true)
      },
      [stopEditing]
    )

    const handleInputKeyDown = useCallback(
      (e: React.KeyboardEvent) => {
        if (e.key === 'Enter') {
          e.preventDefault()
          stopEditing(true)
        } else if (e.key === 'Escape') {
          e.preventDefault()
          stopEditing(false)
        }
      },
      [stopEditing]
    )

    // Стили для отображения содержимого
    const contentStyles: CSSProperties = {
      overflow: availablePx > columnWidth ? 'visible' : 'hidden',
      whiteSpace: 'nowrap',
      ...(isSelected && !multiSelectionActive
        ? { boxShadow: 'inset 0 0 0 2px hsl(var(--primary))' }
        : highlightColor
          ? { boxShadow: 'inset 0 0 0 2px currentColor' }
          : {}),
    }

    const textStyles: CSSProperties = {
      width: availablePx > columnWidth ? availablePx - 8 : columnWidth - 16,
      whiteSpace: 'nowrap',
      overflow: 'hidden',
      textOverflow: 'ellipsis',
      pointerEvents: 'none',
      zIndex: 1,
    }

    return (
      <div
        className={className}
        style={cellStyle}
        onMouseDown={handleMouseDown}
        onMouseEnter={handleMouseEnter}
        onMouseUp={handleMouseUp}
        onClick={handleClick}
        onDoubleClick={handleDoubleClick}
      >
        {isEditing && isSelected ? (
          <input
            ref={activeCellRef as React.RefObject<HTMLInputElement>}
            type="text"
            value={rawValue}
            onChange={e => onCellValueChange(e.target.value)}
            style={{ width: columnWidth - 4 }}
            onBlur={handleInputBlur}
            onKeyDown={handleInputKeyDown}
            className="absolute left-0 top-0 z-20 box-border h-full border-2 border-primary px-2 py-1"
          />
        ) : (
          <div
            className="relative flex h-full w-full items-center px-2"
            style={contentStyles}
          >
            <div
              className="absolute left-1 top-0 flex h-full items-center"
              style={textStyles}
            >
              {displayValue}
            </div>
          </div>
        )}
      </div>
    )
  }
)
