import {
  useEffect,
  useState,
  type FormEvent,
} from 'react'
import * as Dialog from '@radix-ui/react-dialog'
import { X } from 'lucide-react'

import {
  calibrationIconOptions,
  getCalibrationIcon,
} from './utils'
import {
  machineCalibrationService,
  type MachineStateDefinitionPayload,
} from '../../../../entities/machine/api/machineCalibrationService'
import type { MachineStateDefinition } from '../../../../entities/machine/model/types'
import { MotionDialogContent } from '../../../../shared/ui/MotionDialog/MotionDialog'
import { MachineSelect } from '../../../MachinesPage/components/MachineSelect/MachineSelect'

import '../../../EmployeesPage/components/AddEmployeeModal/AddEmployeeModal.scss'

type MachineStateDefinitionModalProps = {
  definition?: MachineStateDefinition | null
  open: boolean
  onOpenChange: (open: boolean) => void
  onSuccess: (context: MachineStateDefinitionModalSuccess) => void | Promise<void>
}

export type MachineStateDefinitionModalSuccess = {
  action: 'create' | 'update'
  previousDefinitions: MachineStateDefinition[]
}

export function MachineStateDefinitionModal({
  definition = null,
  open,
  onOpenChange,
  onSuccess,
}: MachineStateDefinitionModalProps) {
  const isEditMode = Boolean(definition)
  const [name, setName] = useState('')
  const [icon, setIcon] = useState('Activity')
  const [color, setColor] = useState('#2f80ed')
  const [description, setDescription] = useState('')
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [submitError, setSubmitError] = useState<string | null>(null)

  useEffect(() => {
    if (!open) return

    queueMicrotask(() => {
      setSubmitError(null)

      if (definition) {
        setName(definition.name)
        setIcon(definition.icon)
        setColor(definition.color)
        setDescription(definition.description)
        return
      }

      setName('')
      setIcon('Activity')
      setColor('#2f80ed')
      setDescription('')
    })
  }, [definition, open])

  async function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault()

    if (isSubmitting) return

    const payload: MachineStateDefinitionPayload = {
      name,
      icon,
      color,
      description,
    }

    try {
      setIsSubmitting(true)
      setSubmitError(null)

      const previousDefinitions =
        await machineCalibrationService.getMachineStateDefinitionsSnapshot()

      if (isEditMode && definition) {
        await machineCalibrationService.updateMachineStateDefinition(
          definition.id,
          payload,
        )
      } else {
        await machineCalibrationService.createMachineStateDefinition(payload)
      }

      await onSuccess({
        action: isEditMode ? 'update' : 'create',
        previousDefinitions,
      })
      onOpenChange(false)
    } catch (error) {
      setSubmitError(
        error instanceof Error
          ? error.message
          : 'Не удалось сохранить состояние',
      )
    } finally {
      setIsSubmitting(false)
    }
  }

  return (
    <Dialog.Root open={open} onOpenChange={onOpenChange}>
      <MotionDialogContent
        open={open}
        overlayClassName="add-employee-modal__overlay"
        contentClassName="add-employee-modal machine-calibration-modal"
        motionPreset="fade"
      >
        <div className="add-employee-modal__header">
          <div>
            <Dialog.Title className="add-employee-modal__title">
              {isEditMode ? 'Редактировать состояние' : 'Добавить состояние'}
            </Dialog.Title>

            <Dialog.Description className="add-employee-modal__description">
              Справочник хранит смысл состояния без диапазонов вибрации.
            </Dialog.Description>
          </div>

          <Dialog.Close
            className="add-employee-modal__close"
            type="button"
            disabled={isSubmitting}
          >
            <X size={20} />
          </Dialog.Close>
        </div>

        <form className="add-employee-form" onSubmit={handleSubmit}>
          <div className="add-employee-fields__section">
            <label className="add-employee-field">
              <span>Название состояния</span>
              <input
                value={name}
                onChange={(event) => setName(event.target.value)}
                placeholder="Например: Холостой ход"
                disabled={isSubmitting}
                required
              />
            </label>

            <div className="add-employee-form__grid">
              <div className="add-employee-field">
                <span>Иконка</span>
                <MachineSelect
                  value={icon}
                  options={calibrationIconOptions}
                  placeholder="Выберите иконку"
                  disabled={isSubmitting}
                  onChange={setIcon}
                />
              </div>

              <label className="add-employee-field machine-calibration-color-field">
                <span>Цвет</span>
                <div className="machine-calibration-color-control">
                  <span style={{ backgroundColor: color }}>
                    {getCalibrationIcon(icon, 18)}
                  </span>
                  <input
                    type="color"
                    value={color}
                    onChange={(event) => setColor(event.target.value)}
                    disabled={isSubmitting}
                  />
                  <input
                    value={color}
                    onChange={(event) => setColor(event.target.value)}
                    disabled={isSubmitting}
                    placeholder="#2f80ed"
                  />
                </div>
              </label>
            </div>

            <label className="add-employee-field add-machine-field--textarea">
              <span>Описание</span>
              <textarea
                value={description}
                onChange={(event) => setDescription(event.target.value)}
                placeholder="Коротко опишите, что означает это состояние"
                disabled={isSubmitting}
              />
            </label>
          </div>

          {submitError && (
            <div className="add-employee-error">
              {submitError}
            </div>
          )}

          <div className="add-employee-modal__footer">
            <Dialog.Close
              className="add-employee-cancel"
              type="button"
              disabled={isSubmitting}
            >
              Отмена
            </Dialog.Close>

            <button
              className="add-employee-submit"
              type="submit"
              disabled={isSubmitting || !name.trim()}
            >
              {isSubmitting ? 'Сохранение...' : 'Сохранить'}
            </button>
          </div>
        </form>
      </MotionDialogContent>
    </Dialog.Root>
  )
}
