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

import type { Beacon } from '../../../../entities/beacon/model/types'
import { beaconsService } from '../../../../entities/beacon/api/beaconsService'
import type { Machine } from '../../../../entities/machine/model/types'
import { machinesService } from '../../../../entities/machine/api/machinesService'
import { MotionDialogContent } from '../../../../shared/ui/MotionDialog/MotionDialog'
import { MachineSelect } from '../MachineSelect/MachineSelect'

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

type BeaconBindingModalProps = {
  open: boolean
  machine: Machine | null
  onOpenChange: (open: boolean) => void
  onSuccess?: () => void | Promise<void>
}

export function BeaconBindingModal({
  open,
  machine,
  onOpenChange,
  onSuccess,
}: BeaconBindingModalProps) {
  const [freeBeacons, setFreeBeacons] = useState<Beacon[]>([])
  const [beaconId, setBeaconId] = useState('')
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [submitError, setSubmitError] = useState<string | null>(null)
  const beaconOptions = useMemo(
    () => freeBeacons.map((beacon) => ({
      value: String(beacon.id),
      label: beacon.identifier,
      description: beacon.macAddress,
    })),
    [freeBeacons],
  )

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

    let isMounted = true

    async function loadFreeBeacons() {
      const beacons = await beaconsService.getFreeBeacons()

      if (!isMounted) return

      setFreeBeacons(beacons)
      setBeaconId(beacons[0] ? String(beacons[0].id) : '')
      setSubmitError(null)
    }

    loadFreeBeacons()

    return () => {
      isMounted = false
    }
  }, [open])

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

    if (!machine || !beaconId || isSubmitting) return

    try {
      setIsSubmitting(true)
      setSubmitError(null)
      await machinesService.bindBeacon(machine.id, Number(beaconId))
      await onSuccess?.()
      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"
        motionPreset="fade"
      >
        <div className="add-employee-modal__header">
          <div>
            <Dialog.Title className="add-employee-modal__title">
              Привязать маяк
            </Dialog.Title>

            <Dialog.Description className="add-employee-modal__description">
              {machine
                ? `Выберите свободный BLE-маяк для АТТ «${machine.name}».`
                : 'Выберите свободный BLE-маяк для АТТ.'}
            </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">
            <div className="add-employee-field">
              <span>Свободный маяк</span>
              <MachineSelect
                value={beaconId}
                options={beaconOptions}
                placeholder="Выберите свободный маяк"
                emptyText="Свободных маяков нет"
                disabled={isSubmitting || freeBeacons.length === 0}
                onChange={setBeaconId}
              />
            </div>
          </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 || !beaconId}
            >
              {isSubmitting ? 'Привязка...' : 'Привязать'}
            </button>
          </div>
        </form>
      </MotionDialogContent>
    </Dialog.Root>
  )
}
