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

interface TextConfig {
  placeholder?: string
  required?: boolean
  showIncrementButton?: boolean // Новый параметр для отображения кнопки +1
  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,
    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 || []
    return cells.map(target => ({ target, value: value || '' }))
  },
  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>
  ),
  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 [rollingDigits, setRollingDigits] = useState<string[]>([])
    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
      const currentStr = currentNum.toString()
      const newStr = newNum.toString()

      setIsAnimating(true)

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

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

      // Проверяем, увеличивается ли количество разрядов
      const isAddingDigit = newStr.length > currentStr.length

      if (isAddingDigit) {
        // Если добавляется разряд, делаем анимацию сдвига
        setRollingDigits(currentStr.split(''))

        // Анимация сдвига при добавлении разряда
        const duration = 800
        const startTime = Date.now()

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

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

          if (progress < 1) {
            // Плавное появление новой цифры слева и изменение старых
            const easeOutQuad = (t: number) => t * (2 - t)
            const smoothProgress = easeOutQuad(progress)

            // Разбираем целевое число на цифры
            const targetDigits = newStr.split('')
            const currentDigits = currentStr.split('')

            if (smoothProgress > 0.2) {
              // Создаем анимированный массив цифр
              const animatedDigits = targetDigits.map((targetDigit, index) => {
                if (index === 0) {
                  // Первая цифра (новая) - плавно появляется
                  return targetDigit
                } else {
                  // Остальные цифры - плавно меняются от старых к новым
                  const oldDigit = currentDigits[index - 1] || '0'
                  const oldNum = parseInt(oldDigit)
                  const targetNum = parseInt(targetDigit)

                  // Интерполяция между старой и новой цифрой
                  const currentNum =
                    oldNum + (targetNum - oldNum) * smoothProgress

                  // В конце анимации фиксируем на целевой цифре
                  if (progress > 0.9) {
                    return targetDigit
                  }

                  return Math.round(currentNum).toString()
                }
              })

              setRollingDigits(animatedDigits)
            }
          } else {
            // Финал
            setRollingDigits([])
            setIsAnimating(false)
            handleValueChange(newStr)
          }

          if (progress < 1) {
            requestAnimationFrame(animateSlide)
          }
        }

        requestAnimationFrame(animateSlide)
      } else {
        // Обычная анимация для случаев без добавления разряда
        const maxLength = Math.max(currentStr.length, newStr.length)
        const currentPadded = currentStr.padStart(maxLength, '0')
        const newPadded = newStr.padStart(maxLength, '0')

        // Создаем массив с начальными значениями
        setRollingDigits(currentPadded.split(''))

        // Анимация плавного перехода цифр
        const duration = 800
        const startTime = Date.now()

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

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

          if (progress < 1) {
            // Используем функцию сглаживания для более плавной анимации
            const easeOutQuad = (t: number) => t * (2 - t)
            const smoothProgress = easeOutQuad(progress)

            const newRolling = currentPadded
              .split('')
              .map((oldDigit, index) => {
                const targetDigit = newPadded[index]

                // Если цифра не изменилась, оставляем как есть
                if (oldDigit === targetDigit) {
                  return oldDigit
                }

                // Для изменившихся цифр - прямой переход с интерполяцией
                const oldNum = parseInt(oldDigit)
                const targetNum = parseInt(targetDigit)

                // Прямая интерполяция между старой и новой цифрой
                const currentNum =
                  oldNum + (targetNum - oldNum) * smoothProgress

                // В конце анимации фиксируем на целевой цифре
                if (progress > 0.95) {
                  return targetDigit
                }

                return Math.round(currentNum).toString()
              })

            setRollingDigits(newRolling)
          } else {
            // Финал
            setRollingDigits([])
            setIsAnimating(false)
            handleValueChange(newStr)
          }

          if (progress < 1) {
            requestAnimationFrame(animateTransition)
          }
        }

        requestAnimationFrame(animateTransition)
      }
    }

    // Определяем отображаемое значение
    const displayValue =
      isAnimating && rollingDigits.length > 0
        ? rollingDigits.join('').replace(/^0+/, '') || '0'
        : currentValue

    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={displayValue}
            onChange={e => {
              if (!isAnimating) {
                // Автоматически заменяем запятые на точки
                const normalizedValue = e.target.value.replace(/,/g, '.')
                handleValueChange(normalizedValue)
              }
            }}
            required={config.required}
            className={`${config.showIncrementButton ? 'pr-10' : ''} ${
              isAnimating
                ? '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>
    )
  },
}
