import { Badge } from '@/component/ui/badge'
import { Button } from '@/component/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/component/ui/card'
import { Input } from '@/component/ui/input'
import { Label } from '@/component/ui/label'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/component/ui/select'
import { ElementDefinition } from '@/entitiy/element/model/interface'
import {
  AlertCircle,
  Check,
  Droplets,
  Edit3,
  Gauge,
  Radio,
  Thermometer,
  X,
  Zap,
} from 'lucide-react'
import React, { useEffect, useState } from 'react'

interface CalibrationConditions {
  temperature: string
  humidity: string
  pressure: string
  voltage: string
  frequency: string
  lastUpdated: string
  updatedBy?: string
}

interface ValidationResult {
  isValid: boolean
  message?: string
}

interface CalibrationCondInfoProps {
  conditions: CalibrationConditions
  isOutdated: boolean
  onUpdate: (conditions: CalibrationConditions) => Promise<boolean>
}

// Валидационные правила
const validateField = (field: string, value: string): ValidationResult => {
  const numValue = parseFloat(value)

  if (!value.trim()) {
    return { isValid: false, message: 'Поле обязательно' }
  }

  if (isNaN(numValue)) {
    return { isValid: false, message: 'Введите число' }
  }

  switch (field) {
    case 'temperature':
      if (numValue < -40 || numValue > 85) {
        return { isValid: false, message: 'Диапазон: -40...+85°C' }
      }
      break
    case 'humidity':
      if (numValue < 0 || numValue > 100) {
        return { isValid: false, message: 'Диапазон: 0...100%' }
      }
      break
    case 'pressure':
      if (numValue < 80 || numValue > 120) {
        return { isValid: false, message: 'Диапазон: 80...120 кПа' }
      }
      break
    case 'voltage':
      if (numValue < 180 || numValue > 250) {
        return { isValid: false, message: 'Диапазон: 180...250 В' }
      }
      break
    case 'frequency':
      if (numValue < 45 || numValue > 65) {
        return { isValid: false, message: 'Диапазон: 45...65 Гц' }
      }
      break
  }

  return { isValid: true }
}

const formatLastUpdated = (dateString: string) => {
  const date = new Date(dateString)
  const today = new Date()
  const yesterday = new Date(today)
  yesterday.setDate(yesterday.getDate() - 1)

  const weekdayRu = date.toLocaleString('ru-RU', { weekday: 'long' })
  const monthShortRu = date
    .toLocaleString('ru-RU', { month: 'short' })
    .replace(/\./, '')
    .replace(/^./, s => s.toUpperCase())
  const day = date.getDate()
  const time: string = date.toLocaleString('ru-RU', {
    hour: '2-digit',
    minute: '2-digit',
  })

  if (date.toDateString() === today.toDateString()) {
    return `Сегодня в ${time}`
  } else if (date.toDateString() === yesterday.toDateString()) {
    return `Вчера в ${time}`
  } else {
    return `${weekdayRu.replace(/^./, s =>
      s.toUpperCase()
    )} ${day} ${monthShortRu} ${time}`
  }
}

function CalibrationCondInfo({
  conditions,
  isOutdated,
  onUpdate,
}: CalibrationCondInfoProps) {
  const [showModal, setShowModal] = useState(false)
  const [tempConditions, setTempConditions] =
    useState<CalibrationConditions>(conditions)
  const [validationErrors, setValidationErrors] = useState<
    Record<string, string>
  >({})
  const [isLoading, setIsLoading] = useState(false)

  useEffect(() => {
    setTempConditions(conditions)
  }, [conditions])

  const validateForm = () => {
    const errors: Record<string, string> = {}
    const fields = [
      'temperature',
      'humidity',
      'pressure',
      'voltage',
      'frequency',
    ]

    fields.forEach(field => {
      const validation = validateField(
        field,
        tempConditions[field as keyof CalibrationConditions] as string
      )
      if (!validation.isValid && validation.message) {
        errors[field] = validation.message
      }
    })

    setValidationErrors(errors)
    return Object.keys(errors).length === 0
  }

  const handleFieldChange = (field: string, value: string) => {
    setTempConditions(prev => ({ ...prev, [field]: value }))

    // Валидация в реальном времени
    const validation = validateField(field, value)
    setValidationErrors(prev => ({
      ...prev,
      [field]: validation.isValid ? '' : validation.message || '',
    }))
  }

  const handleSave = async () => {
    if (!validateForm()) return

    setIsLoading(true)
    const newConditions = {
      ...tempConditions,
      lastUpdated: new Date().toISOString(),
    }

    const success = await onUpdate(newConditions)
    setIsLoading(false)

    if (success) {
      setShowModal(false)
    } else {
      alert('Не удалось сохранить условия поверки')
    }
  }

  const openModal = () => {
    setTempConditions(conditions)
    setValidationErrors({})
    setShowModal(true)
    // Устанавливаем фокус на первое поле через небольшую задержку
    setTimeout(() => {
      const firstInput = document.getElementById(
        'modal-temperature'
      ) as HTMLInputElement
      if (firstInput) {
        firstInput.focus()
        firstInput.select()
      }
    }, 100)
  }

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (
      e.key === 'Enter' &&
      !Object.keys(validationErrors).some(key => validationErrors[key])
    ) {
      handleSave()
    }
    if (e.key === 'Escape') {
      setShowModal(false)
    }
  }

  const fieldConfigs = [
    {
      key: 'temperature',
      label: 'Температура',
      icon: Thermometer,
      unit: '°C',
      placeholder: '20',
    },
    {
      key: 'humidity',
      label: 'Влажность',
      icon: Droplets,
      unit: '%',
      placeholder: '65',
    },
    {
      key: 'pressure',
      label: 'Давление',
      icon: Gauge,
      unit: 'кПа',
      placeholder: '101.3',
    },
    {
      key: 'voltage',
      label: 'Напряжение',
      icon: Zap,
      unit: 'В',
      placeholder: '220',
    },
    {
      key: 'frequency',
      label: 'Частота',
      icon: Radio,
      unit: 'Гц',
      placeholder: '50',
    },
  ]

  return (
    <>
      {/* Компактное отображение */}
      <div className="flex items-center gap-3 rounded-lg border bg-muted/50 px-3 py-2">
        <div className="flex items-center gap-3 text-xs">
          {fieldConfigs.map(({ key, icon: Icon, unit }) => (
            <div key={key} className="flex items-center gap-1">
              <Icon className="h-3 w-3 text-muted-foreground" />
              <span className="text-foreground">
                {conditions[key as keyof CalibrationConditions]}
                {unit}
              </span>
            </div>
          ))}
        </div>
        <Button
          variant="ghost"
          size="icon"
          onClick={openModal}
          className={`h-6 w-6 p-0 ${
            isOutdated ? 'text-yellow-600 hover:text-yellow-700' : ''
          }`}
        >
          <Edit3 className="h-3 w-3" />
        </Button>
        {isOutdated && (
          <div className="h-2 w-2 animate-pulse rounded-full bg-yellow-500" />
        )}
      </div>

      {/* Модальное окно */}
      {showModal && (
        <div
          className="fixed inset-0 z-50 flex items-center justify-center overflow-y-auto bg-black/50 p-4"
          onKeyDown={handleKeyDown}
        >
          <div className="flex min-h-full items-center justify-center p-4">
            <Card className="mx-auto my-8 w-full max-w-2xl">
              <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-4">
                <CardTitle className="text-lg">Условия поверки</CardTitle>
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => setShowModal(false)}
                >
                  <X className="h-4 w-4" />
                </Button>
              </CardHeader>
              <CardContent className="space-y-6">
                <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
                  {fieldConfigs.map(
                    ({ key, label, icon: Icon, unit, placeholder }) => {
                      const hasError = validationErrors[key]
                      const isValid =
                        tempConditions[key as keyof CalibrationConditions] &&
                        !hasError

                      return (
                        <div key={key} className="space-y-2">
                          <Label
                            htmlFor={`modal-${key}`}
                            className="flex items-center gap-2"
                          >
                            <Icon className="h-4 w-4 text-muted-foreground" />
                            {label}
                          </Label>
                          <div className="space-y-1">
                            <div className="flex items-center gap-2">
                              <Input
                                id={`modal-${key}`}
                                value={
                                  tempConditions[
                                    key as keyof CalibrationConditions
                                  ] as string
                                }
                                onChange={e =>
                                  handleFieldChange(key, e.target.value)
                                }
                                onKeyDown={e => {
                                  if (e.key === 'Enter') {
                                    e.preventDefault()
                                    handleSave()
                                  }
                                }}
                                className={`text-center [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none ${
                                  hasError
                                    ? 'border-destructive focus-visible:ring-destructive'
                                    : isValid
                                      ? 'border-green-500 focus-visible:ring-green-500'
                                      : ''
                                }`}
                                placeholder={placeholder}
                                type="number"
                                step="0.1"
                              />
                              <div className="flex min-w-[3rem] items-center gap-1">
                                <span className="text-sm text-muted-foreground">
                                  {unit}
                                </span>
                                {isValid && (
                                  <Check className="h-4 w-4 text-green-500" />
                                )}
                                {hasError && (
                                  <div className="group relative">
                                    <AlertCircle className="h-4 w-4 cursor-help text-destructive" />
                                    <div className="pointer-events-none absolute bottom-full left-1/2 z-10 mb-2 -translate-x-1/2 transform whitespace-nowrap rounded border bg-popover px-2 py-1 text-xs text-popover-foreground opacity-0 shadow-md transition-opacity group-hover:opacity-100">
                                      {hasError}
                                    </div>
                                  </div>
                                )}
                              </div>
                            </div>
                          </div>
                        </div>
                      )
                    }
                  )}
                </div>

                <div className="flex items-center justify-between border-t pt-4 text-xs">
                  <div className="flex items-center gap-4">
                    <span className="text-muted-foreground">
                      Обновлено: {formatLastUpdated(conditions.lastUpdated)}
                    </span>
                  </div>
                  {isOutdated && (
                    <Badge variant="destructive" className="text-xs">
                      Устарели
                    </Badge>
                  )}
                </div>

                <div className="flex gap-3 pt-2">
                  <Button
                    onClick={handleSave}
                    className="flex-1"
                    disabled={
                      isLoading ||
                      Object.keys(validationErrors).some(
                        key => validationErrors[key]
                      )
                    }
                  >
                    {isLoading ? 'Сохранение...' : 'Сохранить'}
                  </Button>
                  <Button
                    variant="outline"
                    onClick={() => setShowModal(false)}
                    className="flex-1"
                    disabled={isLoading}
                  >
                    Отмена
                  </Button>
                </div>
              </CardContent>
            </Card>
          </div>
        </div>
      )}
    </>
  )
}

interface CalibrationConditionsConfig {
  targetCells: any[]
  defaultConditions?: CalibrationConditions
  cellMapping?: {
    [key: string]: string // параметр -> ячейка из targetCells (по индексу)
  }
}

export const calibrationConditionsDefinition: ElementDefinition<
  CalibrationConditionsConfig,
  CalibrationConditions
> = {
  type: 'calibration_conditions',
  label: 'Условия калибровки',
  icon: <Thermometer className="h-4 w-4" />,
  version: 1,
  defaultConfig: {
    targetCells: [],
    cellMapping: {},
    defaultConditions: {
      temperature: '20',
      humidity: '65',
      pressure: '101.3',
      voltage: '220',
      frequency: '50',
      lastUpdated: new Date().toISOString(),
    },
  },
  mapToCells: cfg => {
    // Используем только ячейки, указанные пользователем в targetCells
    return cfg.targetCells || []
  },
  mapToCellValues: (config, value) => {
    // Используем targetCells из конфигурации
    const cells = config.targetCells || []
    const cellMapping = config.cellMapping || {}

    // Если значение не объект, возвращаем пустые значения
    if (!value || typeof value !== 'object') {
      return cells.map(target => ({
        target,
        value: '',
      }))
    }

    // Создаем обратное сопоставление: индекс ячейки -> параметр
    const reversedMapping: { [cellIndex: string]: string } = {}
    Object.entries(cellMapping).forEach(([param, cellIndex]) => {
      reversedMapping[cellIndex] = param
    })

    return cells.map((target, idx) => {
      const paramKey = reversedMapping[idx.toString()]
      const paramValue = paramKey ? (value as any)[paramKey] : ''

      return {
        target,
        value: paramValue || '',
      }
    })
  },
  Editor: ({ config, onChange }) => {
    const availableParams = [
      { key: 'temperature', label: 'Температура' },
      { key: 'humidity', label: 'Влажность' },
      { key: 'pressure', label: 'Давление' },
      { key: 'voltage', label: 'Напряжение' },
      { key: 'frequency', label: 'Частота' },
      { key: 'lastUpdated', label: 'Дата обновления' },
    ]

    const targetCells = config.targetCells || []
    const cellMapping = config.cellMapping || {}

    // Функция для создания автоматического сопоставления по порядку
    const createAutoMapping = () => {
      const newMapping: { [key: string]: string } = {}
      const paramKeys = availableParams.map(p => p.key)

      // Сопоставляем первые N параметров с первыми N ячейками
      targetCells.forEach((_, index) => {
        if (index < paramKeys.length) {
          newMapping[paramKeys[index]] = index.toString()
        }
      })

      onChange({
        ...config,
        cellMapping: newMapping,
      })
    }

    const updateCellMapping = (param: string, cellIndex: string) => {
      const newMapping = { ...cellMapping }
      if (cellIndex === '' || cellIndex === 'none') {
        delete newMapping[param]
      } else {
        newMapping[param] = cellIndex
      }
      onChange({
        ...config,
        cellMapping: newMapping,
      })
    }

    return (
      <div className="space-y-4">
        <div className="rounded-lg border border-gray-200 bg-gray-50 p-4">
          <p className="text-sm text-gray-600">
            Элемент "Условия калибровки" позволяет вводить и отслеживать
            параметры окружающей среды при проведении измерений. Поддерживает
            валидацию значений и отслеживание времени обновления.
          </p>
        </div>

        {/* Сопоставление параметров с ячейками */}
        {targetCells.length > 0 && (
          <div className="space-y-2">
            <div className="flex items-center justify-between">
              <Label className="text-sm font-medium">
                Сопоставление с ячейками
              </Label>
              <Button
                variant="outline"
                size="sm"
                onClick={createAutoMapping}
                className="h-7 px-2 text-xs"
              >
                Автозаполнение
              </Button>
            </div>
            <div className="space-y-3 rounded-lg border border-gray-200 p-4">
              {availableParams.map(param => (
                <div key={param.key} className="flex items-center gap-3">
                  <div className="min-w-[120px]">
                    <span className="text-sm text-gray-700">{param.label}</span>
                  </div>
                  <div className="flex-1">
                    <Select
                      value={cellMapping[param.key] || 'none'}
                      onValueChange={value =>
                        updateCellMapping(param.key, value)
                      }
                    >
                      <SelectTrigger className="w-full">
                        <SelectValue placeholder="Не указано" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="none">Не указано</SelectItem>
                        {targetCells.map((cell, index) => (
                          <SelectItem key={index} value={index.toString()}>
                            {cell.sheet}!{cell.cell}{' '}
                            {cell.displayName ? `(${cell.displayName})` : ''}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </div>
              ))}
            </div>
            <p className="text-xs text-gray-500">
              Настройте какой параметр условий калибровки будет записан в какую
              ячейку. Используйте кнопку "Автозаполнение" для автоматического
              сопоставления по порядку.
            </p>
          </div>
        )}

        <div className="space-y-2">
          <label className="text-sm font-medium">Параметры по умолчанию</label>
          <div className="grid grid-cols-2 gap-4 rounded-lg border border-gray-200 p-4">
            <div className="space-y-2">
              <label className="text-xs font-medium text-gray-600">
                Температура (°C)
              </label>
              <Input
                type="number"
                value={config.defaultConditions?.temperature || '20'}
                onChange={e =>
                  onChange({
                    ...config,
                    defaultConditions: {
                      ...config.defaultConditions,
                      temperature: e.target.value,
                      humidity: config.defaultConditions?.humidity || '65',
                      pressure: config.defaultConditions?.pressure || '101.3',
                      voltage: config.defaultConditions?.voltage || '220',
                      frequency: config.defaultConditions?.frequency || '50',
                      lastUpdated:
                        config.defaultConditions?.lastUpdated ||
                        new Date().toISOString(),
                    },
                  })
                }
                placeholder="20"
              />
            </div>
            <div className="space-y-2">
              <label className="text-xs font-medium text-gray-600">
                Влажность (%)
              </label>
              <Input
                type="number"
                value={config.defaultConditions?.humidity || '65'}
                onChange={e =>
                  onChange({
                    ...config,
                    defaultConditions: {
                      ...config.defaultConditions,
                      temperature:
                        config.defaultConditions?.temperature || '20',
                      humidity: e.target.value,
                      pressure: config.defaultConditions?.pressure || '101.3',
                      voltage: config.defaultConditions?.voltage || '220',
                      frequency: config.defaultConditions?.frequency || '50',
                      lastUpdated:
                        config.defaultConditions?.lastUpdated ||
                        new Date().toISOString(),
                    },
                  })
                }
                placeholder="65"
              />
            </div>
            <div className="space-y-2">
              <label className="text-xs font-medium text-gray-600">
                Давление (кПа)
              </label>
              <Input
                type="number"
                value={config.defaultConditions?.pressure || '101.3'}
                onChange={e =>
                  onChange({
                    ...config,
                    defaultConditions: {
                      ...config.defaultConditions,
                      temperature:
                        config.defaultConditions?.temperature || '20',
                      humidity: config.defaultConditions?.humidity || '65',
                      pressure: e.target.value,
                      voltage: config.defaultConditions?.voltage || '220',
                      frequency: config.defaultConditions?.frequency || '50',
                      lastUpdated:
                        config.defaultConditions?.lastUpdated ||
                        new Date().toISOString(),
                    },
                  })
                }
                placeholder="101.3"
              />
            </div>
            <div className="space-y-2">
              <label className="text-xs font-medium text-gray-600">
                Напряжение (В)
              </label>
              <Input
                type="number"
                value={config.defaultConditions?.voltage || '220'}
                onChange={e =>
                  onChange({
                    ...config,
                    defaultConditions: {
                      ...config.defaultConditions,
                      temperature:
                        config.defaultConditions?.temperature || '20',
                      humidity: config.defaultConditions?.humidity || '65',
                      pressure: config.defaultConditions?.pressure || '101.3',
                      voltage: e.target.value,
                      frequency: config.defaultConditions?.frequency || '50',
                      lastUpdated:
                        config.defaultConditions?.lastUpdated ||
                        new Date().toISOString(),
                    },
                  })
                }
                placeholder="220"
              />
            </div>
            <div className="space-y-2">
              <label className="text-xs font-medium text-gray-600">
                Частота (Гц)
              </label>
              <Input
                type="number"
                value={config.defaultConditions?.frequency || '50'}
                onChange={e =>
                  onChange({
                    ...config,
                    defaultConditions: {
                      ...config.defaultConditions,
                      temperature:
                        config.defaultConditions?.temperature || '20',
                      humidity: config.defaultConditions?.humidity || '65',
                      pressure: config.defaultConditions?.pressure || '101.3',
                      voltage: config.defaultConditions?.voltage || '220',
                      frequency: e.target.value,
                      lastUpdated:
                        config.defaultConditions?.lastUpdated ||
                        new Date().toISOString(),
                    },
                  })
                }
                placeholder="50"
              />
            </div>
          </div>
        </div>
      </div>
    )
  },
  Preview: ({ config }) => (
    <div className="space-y-3">
      <div className="text-sm font-medium text-gray-700">Предпросмотр</div>
      <div className="rounded-lg border border-gray-200 bg-white p-4">
        <CalibrationCondInfo
          conditions={
            config.defaultConditions || {
              temperature: '20',
              humidity: '65',
              pressure: '101.3',
              voltage: '220',
              frequency: '50',
              lastUpdated: new Date().toISOString(),
            }
          }
          isOutdated={false}
          onUpdate={async () => true}
        />
      </div>
    </div>
  ),
  Render: ({ config, value, onChange }) => {
    // Если значение не установлено, используем defaultConditions из конфигурации
    const conditions = value ||
      config.defaultConditions || {
        temperature: '20',
        humidity: '65',
        pressure: '101.3',
        voltage: '220',
        frequency: '50',
        lastUpdated: new Date().toISOString(),
      }

    // Проверяем, устарели ли условия (больше 24 часов)
    const lastUpdated = new Date(conditions.lastUpdated)
    const now = new Date()
    const isOutdated =
      now.getTime() - lastUpdated.getTime() > 24 * 60 * 60 * 1000

    return (
      <CalibrationCondInfo
        conditions={conditions}
        isOutdated={isOutdated}
        onUpdate={async newConditions => {
          onChange?.(newConditions)
          return true
        }}
      />
    )
  },
}
