import { ElementDefinition } from '@/entity/element/model/interface'
import { CellsBadge } from '@/entity/element/ui/cellsBadge'
import { Plus, Save, SaveOff, Type } from 'lucide-react'
import { useEffect, useState } from 'react'
import { Checkbox } from 'shared/ui/checkbox'
import { Input } from 'shared/ui/input'

interface TextConfig {
  placeholder?: string
  required?: boolean
  showIncrementButton?: boolean // Новый параметр для отображения кнопки +1
  addZeroWidthSpace?: boolean // Добавляем невидимый символ \u200B к значению
  targetCells: any[]
  name?: string
  id?: string // Добавляем id для совместимости с TemplateElement
}

// Утилиты для работы с localStorage
const getLocalStorageKey = (type: string, id: string) => `${type}_${id}`

const saveToLocalStorage = (key: string, value: string) => {
  try {
    localStorage.setItem(key, value)
  } catch (error) {
    console.warn('Failed to save to localStorage:', error)
  }
}

const getFromLocalStorage = (key: string): string => {
  try {
    return localStorage.getItem(key) || ''
  } catch (error) {
    console.warn('Failed to get from localStorage:', error)
    return ''
  }
}

const removeFromLocalStorage = (key: string) => {
  try {
    localStorage.removeItem(key)
  } catch (error) {
    console.warn('Failed to remove from localStorage:', error)
  }
}

export const textDefinition: ElementDefinition<TextConfig, string> = {
  type: 'text',
  label: 'Текстовое поле',
  icon: <Type className="h-4 w-4" />,
  version: 1,
  defaultConfig: {
    placeholder: '',
    required: false,
    showIncrementButton: false,
    addZeroWidthSpace: false,
    targetCells: [],
    name: '',
  },
  getInitialValue: config => {
    // Используем id из config (который приходит из TemplateElement)
    if (config.id) {
      const key = getLocalStorageKey('text', config.id)
      return getFromLocalStorage(key)
    }
    return ''
  },
  mapToCells: config => config.targetCells || [],
  mapToCellValues: (config, value) => {
    const cells = config.targetCells || []
    const cellValue = config.addZeroWidthSpace
      ? `\u200B${value || ''}`
      : value || ''
    return cells.map(target => ({ target, value: cellValue }))
  },
  Editor: ({ config, onChange }) => (
    <div className="space-y-4">
      <div className="flex items-center space-x-2">
        <Checkbox
          id="showIncrementButton"
          checked={config.showIncrementButton || false}
          onCheckedChange={checked =>
            onChange({ ...config, showIncrementButton: !!checked })
          }
        />
        <label
          htmlFor="showIncrementButton"
          className="text-sm font-medium text-gray-900"
        >
          Показывать кнопку +1
        </label>
      </div>
      <div className="flex items-center space-x-2">
        <Checkbox
          id="addZeroWidthSpace"
          checked={config.addZeroWidthSpace || false}
          onCheckedChange={checked =>
            onChange({ ...config, addZeroWidthSpace: !!checked })
          }
        />
        <label
          htmlFor="addZeroWidthSpace"
          className="text-sm font-medium text-gray-900"
        >
          Только текстовое значение
        </label>
      </div>
    </div>
  ),
  Preview: ({ config }) => (
    <div className="space-y-1">
      {config.name && (
        <label className="text-sm font-medium text-gray-900">
          {config.name}
          {config.required && <span className="ml-1 text-red-500">*</span>}
        </label>
      )}
      <div className="relative flex items-center">
        <Input
          placeholder={config.placeholder}
          className={`w-full ${config.showIncrementButton ? 'pr-10' : ''}`}
        />
        {config.showIncrementButton && (
          <button
            className="absolute right-1 flex h-8 w-8 items-center justify-center rounded-md bg-blue-500 text-white"
            disabled
          >
            <Plus className="h-4 w-4" />
          </button>
        )}
      </div>
    </div>
  ),
  Render: ({ config, value, onChange }) => {
    const [localStorageEnabled, setLocalStorageEnabled] = useState(false)
    const [currentValue, setCurrentValue] = useState(value || '')
    const [isAnimating, setIsAnimating] = useState(false)
    const [animatingDigits, setAnimatingDigits] = useState<(number | null)[]>(
      []
    )
    const [flyingDigit, setFlyingDigit] = useState<{
      show: boolean
      x: number
      y: number
    }>({ show: false, x: 0, y: 0 })

    // Инициализация состояния localStorage из сохраненных данных
    useEffect(() => {
      if (config.id) {
        const key = getLocalStorageKey('text', config.id)
        const savedValue = getFromLocalStorage(key)

        // Если есть сохраненное значение, включаем localStorage и загружаем его
        if (savedValue) {
          setLocalStorageEnabled(true)
          if (savedValue !== currentValue) {
            setCurrentValue(savedValue)
            onChange?.(savedValue)
          }
        }
      }
    }, [config.id])

    // Синхронизация внешнего значения
    useEffect(() => {
      if (value !== currentValue) {
        setCurrentValue(value || '')
      }
    }, [value])

    const handleValueChange = (newValue: string) => {
      setCurrentValue(newValue)
      onChange?.(newValue)

      // Сохранение в localStorage если включено
      if (localStorageEnabled && config.id) {
        const key = getLocalStorageKey('text', config.id)
        saveToLocalStorage(key, newValue)
      }
    }

    const handleLocalStorageToggle = () => {
      const newEnabled = !localStorageEnabled
      setLocalStorageEnabled(newEnabled)

      if (config.id) {
        const key = getLocalStorageKey('text', config.id)

        if (newEnabled) {
          // Включаем localStorage - сохраняем текущее значение
          saveToLocalStorage(key, currentValue)
        } else {
          // Выключаем localStorage - удаляем сохраненное значение
          removeFromLocalStorage(key)
        }
      }
    }

    const handleIncrementClick = () => {
      if (isAnimating) return

      const currentNum = parseFloat(currentValue) || 0
      const newNum = currentNum + 1

      setIsAnimating(true)

      // Получаем позицию кнопки для анимации вылета
      const buttonElement = document.querySelector(
        '[data-increment-button]'
      ) as HTMLElement
      if (buttonElement) {
        const rect = buttonElement.getBoundingClientRect()

        setFlyingDigit({
          show: true,
          x: rect.left + rect.width / 2,
          y: rect.top + rect.height / 2,
        })
      }

      // Убираем летящую цифру через 400мс
      setTimeout(() => {
        setFlyingDigit(prev => ({ ...prev, show: false }))
      }, 400)

      // Преобразуем числа в массивы цифр
      const currentStr = currentNum.toString()
      const newStr = newNum.toString()

      // Определяем максимальную длину для выравнивания
      const maxLength = Math.max(currentStr.length, newStr.length)
      const currentDigits = currentStr
        .padStart(maxLength, '0')
        .split('')
        .map(d => parseInt(d))
      const newDigits = newStr
        .padStart(maxLength, '0')
        .split('')
        .map(d => parseInt(d))

      // Инициализируем массив анимируемых цифр
      setAnimatingDigits(currentDigits)

      // Анимация всех цифр
      const startTime = Date.now()
      const duration = 600

      const animateDigits = () => {
        const elapsed = Date.now() - startTime
        const progress = Math.min(elapsed / duration, 1)

        // Используем easing функцию для плавности
        const easeOutQuad = (t: number) => t * (2 - t)
        const smoothProgress = easeOutQuad(progress)

        // Анимируем каждую цифру отдельно
        const currentAnimatedDigits = currentDigits.map((startDigit, index) => {
          const endDigit = newDigits[index]

          // Если цифра не изменилась, возвращаем исходную
          if (startDigit === endDigit) {
            return startDigit
          }

          // Интерполируем между старой и новой цифрой
          const currentDigit =
            startDigit + (endDigit - startDigit) * smoothProgress
          return Math.round(currentDigit)
        })

        setAnimatingDigits(currentAnimatedDigits)

        if (progress < 1) {
          requestAnimationFrame(animateDigits)
        } else {
          setAnimatingDigits([])
          setIsAnimating(false)
          handleValueChange(newNum.toString())
        }
      }

      requestAnimationFrame(animateDigits)
    }

    // Проверяем, является ли текущее значение числом
    const isNumericValue =
      !isNaN(parseFloat(currentValue)) && isFinite(parseFloat(currentValue))

    // Функция для отображения значения с анимированными цифрами
    const getDisplayValue = () => {
      if (!isAnimating || !isNumericValue || animatingDigits.length === 0) {
        return currentValue
      }

      // Собираем число из анимированных цифр и убираем ведущие нули
      const animatedStr = animatingDigits.join('')
      return animatedStr.replace(/^0+/, '') || '0'
    }

    return (
      <div className="relative space-y-1">
        {/* Летящая единичка */}
        {flyingDigit.show && (
          <>
            <style>
              {`
                @keyframes flyToInput {
                  0% {
                    transform: translate(-50%, -50%) scale(1);
                    opacity: 1;
                  }
                  50% {
                    transform: translate(-150%, -100%) scale(1.2);
                    opacity: 0.8;
                  }
                  100% {
                    transform: translate(-300%, -150%) scale(0.8);
                    opacity: 0;
                  }
                }
              `}
            </style>
            <div
              className="pointer-events-none fixed z-50 text-2xl font-bold text-blue-500"
              style={{
                left: flyingDigit.x,
                top: flyingDigit.y,
                transform: 'translate(-50%, -50%)',
                animation: 'flyToInput 400ms ease-out forwards',
              }}
            >
              +1
            </div>
          </>
        )}

        {/* Бейджи в правом верхнем углу */}
        <div className="absolute right-0 top-0 z-10 flex items-center gap-1">
          {/* Галочка сохранения */}
          {config.id && (
            <div className="group/save">
              <button
                onClick={handleLocalStorageToggle}
                className="cursor-pointer"
              >
                {localStorageEnabled ? (
                  <Save className="h-3 w-3 text-green-600 opacity-80 transition-opacity hover:opacity-100" />
                ) : (
                  <SaveOff className="h-3 w-3 cursor-help text-gray-500 opacity-60 transition-opacity hover:opacity-100" />
                )}
              </button>
              <div className="pointer-events-none absolute right-0 top-full z-50 mt-2 whitespace-nowrap rounded bg-gray-900 p-2 text-xs text-white opacity-0 shadow-lg transition-opacity group-hover/save:opacity-100">
                <div className="font-medium">
                  {localStorageEnabled
                    ? 'Автосохранение включено'
                    : 'Автосохранение выключено'}
                </div>
                <div className="text-gray-300">
                  {localStorageEnabled
                    ? 'Значение сохраняется в браузере'
                    : 'Нажмите, чтобы включить автосохранение'}
                </div>
              </div>
            </div>
          )}

          {/* Бейдж ячеек */}
          <CellsBadge targetCells={config.targetCells} className="" />
        </div>

        {/* Лейбл поля */}
        {config.name && (
          <label className="text-sm font-medium text-gray-900">
            {config.name}
            {config.required && <span className="ml-1 text-red-500">*</span>}
          </label>
        )}

        {/* Поле ввода с кнопкой */}
        <div className="relative flex items-center">
          <Input
            placeholder={config.placeholder}
            value={getDisplayValue()}
            onChange={e => {
              if (!isAnimating) {
                // Автоматически заменяем запятые на точки
                const normalizedValue = e.target.value.replace(/,/g, '.')
                handleValueChange(normalizedValue)
              }
            }}
            required={config.required}
            className={`${config.showIncrementButton ? 'pr-10' : ''} ${
              isAnimating && isNumericValue
                ? 'font-mono text-lg font-bold tracking-wider text-blue-600 transition-all duration-300'
                : ''
            }`}
            readOnly={isAnimating}
          />

          {/* Кнопка +1 */}
          {config.showIncrementButton && (
            <button
              data-increment-button
              onClick={handleIncrementClick}
              disabled={isAnimating}
              className={`absolute right-1 z-10 flex h-8 w-8 items-center justify-center rounded-md transition-all duration-300 hover:bg-blue-600 disabled:opacity-75 ${
                isAnimating
                  ? 'scale-125 bg-green-500 shadow-xl ring-4 ring-green-300 ring-opacity-50'
                  : 'scale-100 bg-blue-500 hover:shadow-lg'
              }`}
              title="Увеличить на 1"
            >
              <Plus
                className={`h-4 w-4 text-white transition-all duration-500 ${
                  isAnimating ? 'rotate-180 scale-150' : 'rotate-0 scale-100'
                }`}
              />
            </button>
          )}
        </div>
      </div>
    )
  },
}
