// frontend\src\pages\devices\CameraDetailsModal.tsx

import { type FormEvent } from 'react'
import { XMarkIcon } from '@heroicons/react/24/outline'
import {
  CheckIcon,
  VideoCameraIcon,
} from '@heroicons/react/20/solid'
import Modal from '../../components/Modal'
import Button from '../../components/Button'
import Switch from '../../components/Switch'
import LoadingSpinner from '../../components/LoadingSpinner'
import type { Device, MilestoneCameraDetail } from '../../components/types'

type CameraDetailsModalProps = {
  open: boolean
  setOpen: (open: boolean) => void
  device: Device | null
  childDevice: NonNullable<Device['milestoneChildDevices']>[number] | null
  camera: MilestoneCameraDetail | null
  isLoading: boolean
  isSaving: boolean
  error: string | null
  onSubmit: (event: FormEvent<HTMLFormElement>) => void
}

function inputClassName(disabled = false) {
  return [
    'block w-full rounded-md px-3 py-1.5 text-sm outline-1 -outline-offset-1',
    'bg-white text-gray-900 outline-gray-300',
    'focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600',
    'dark:bg-white/5 dark:text-white dark:outline-white/10 dark:focus:outline-indigo-500',
    disabled && 'cursor-not-allowed bg-gray-50 text-gray-500 dark:bg-white/10 dark:text-gray-400',
  ]
    .filter(Boolean)
    .join(' ')
}

export default function CameraDetailsModal({
  open,
  setOpen,
  device,
  childDevice,
  camera,
  isLoading,
  isSaving,
  error,
  onSubmit,
}: CameraDetailsModalProps) {
  const title =
    childDevice?.displayName ||
    childDevice?.name ||
    'Kamera bearbeiten'

  const streams = camera?.streams ?? []

  const selectedRecordingStorageLabel = camera?.recordingStorage
    ? camera.recordingStorage.displayName ||
      camera.recordingStorage.name ||
      camera.recordingStorage.id
    : ''

  const recordingStorageOptions = (() => {
    const options = new Map<string, string>()

    if (camera?.recordingStorage?.id) {
      options.set(camera.recordingStorage.id, selectedRecordingStorageLabel)
    }

    for (const storage of camera?.archiveStorages ?? []) {
      options.set(
        storage.id,
        storage.displayName || storage.name || storage.id,
      )
    }

    return Array.from(options.entries()).map(([value, label]) => ({
      value,
      label,
    }))
  })()

  return (
    <Modal
      open={open}
      setOpen={setOpen}
      zIndexClassName="z-[10000]"
      panelClassName="max-h-[calc(100dvh-2rem)] max-w-5xl bg-white dark:bg-gray-900"
    >
      <form
        onSubmit={onSubmit}
        className="flex h-[calc(100dvh-2rem)] max-h-[calc(100dvh-2rem)] flex-col"
      >
        <div className="flex items-start justify-between border-b border-gray-200 bg-gray-100 px-4 py-4 sm:px-6 dark:border-white/10 dark:bg-gray-800">
          <div>
            <h3 className="flex items-center gap-2 text-base font-semibold text-gray-900 dark:text-white">
              <VideoCameraIcon
                aria-hidden="true"
                className="size-5 text-indigo-600 dark:text-indigo-400"
              />
              <span>{title}</span>
            </h3>

            <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
              {device?.milestoneDisplayName || device?.inventoryNumber || 'Milestone-Kamera'}
            </p>
          </div>

          <Button
            type="button"
            variant="secondary"
            color="gray"
            size="sm"
            disabled={isSaving}
            onClick={() => setOpen(false)}
          >
            <span className="sr-only">Schließen</span>
            <XMarkIcon aria-hidden="true" className="size-5" />
          </Button>
        </div>

        <div className="min-h-0 flex-1 overflow-y-auto px-4 py-6 sm:px-6">
          {isLoading && (
            <div className="flex min-h-32 items-center justify-center rounded-md border border-dashed border-gray-200 p-4 dark:border-white/10">
              <LoadingSpinner
                size="md"
                label="Kamera-Details werden geladen..."
                className="text-indigo-600 dark:text-indigo-400"
              />
            </div>
          )}

          {error && (
            <div className="mb-4 rounded-md bg-red-50 p-4 text-sm text-red-700 dark:bg-red-900/30 dark:text-red-300">
              {error}
            </div>
          )}

          {!isLoading && camera && (
            <div className="space-y-6">
              <section className="rounded-lg border border-gray-200 bg-white p-4 shadow-xs dark:border-white/10 dark:bg-white/5">
                <div className="border-b border-gray-200 pb-3 dark:border-white/10">
                  <h4 className="text-sm font-semibold text-gray-900 dark:text-white">
                    Allgemein
                  </h4>
                  <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
                    Basisdaten und Aufzeichnungsoptionen der Kamera.
                  </p>
                </div>

                <div className="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-6">
                  <div className="sm:col-span-3 rounded-md border border-gray-200 px-3 py-3 dark:border-white/10">
                    <Switch
                      id="cameraEnabled"
                      name="enabled"
                      label="Kamera aktiviert"
                      defaultChecked={camera.enabled}
                    />
                  </div>

                  <div className="sm:col-span-3 rounded-md border border-gray-200 px-3 py-3 dark:border-white/10">
                    <Switch
                      id="cameraRecordingEnabled"
                      name="recordingEnabled"
                      label="Aufzeichnung aktiviert"
                      defaultChecked={camera.recordingEnabled}
                    />
                  </div>

                  <div className="sm:col-span-3 rounded-md border border-gray-200 px-3 py-3 dark:border-white/10">
                    <Switch
                      id="cameraRecordKeyframesOnly"
                      name="recordKeyframesOnly"
                      label="Nur Keyframes aufzeichnen"
                      defaultChecked={camera.recordKeyframesOnly}
                    />
                  </div>

                  <div className="sm:col-span-3">
                    <label
                      htmlFor="recordingFramerate"
                      className="block text-sm/6 font-medium text-gray-900 dark:text-white"
                    >
                      Aufnahme-FPS
                    </label>
                    <div className="mt-2">
                      <input
                        id="recordingFramerate"
                        name="recordingFramerate"
                        type="number"
                        min="0"
                        step="1"
                        defaultValue={camera.recordingFramerate ?? ''}
                        className={inputClassName()}
                      />
                    </div>
                  </div>

                  <div className="sm:col-span-6">
                    <label
                      htmlFor="recordingStorageId"
                      className="block text-sm/6 font-medium text-gray-900 dark:text-white"
                    >
                      Recording-Storage
                    </label>

                    {camera.recordingStorage?.id && (
                      <p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
                        Gewählt: {selectedRecordingStorageLabel}
                        {camera.recordingStorage.diskPath
                          ? ` · ${camera.recordingStorage.diskPath}`
                          : ''}
                        {camera.recordingStorage.mounted === false
                          ? ' · nicht gemountet'
                          : ''}
                      </p>
                    )}

                    <div className="mt-2">
                      <select
                        id="recordingStorageId"
                        name="recordingStorageId"
                        defaultValue={camera.recordingStorage?.id ?? ''}
                        className={inputClassName()}
                      >
                        <option value="">Kein Storage gewählt</option>
                        {recordingStorageOptions.map((storage) => (
                          <option key={storage.value} value={storage.value}>
                            {storage.label}
                          </option>
                        ))}
                      </select>
                    </div>
                  </div>
                </div>
              </section>

              <section className="rounded-lg border border-gray-200 bg-white p-4 shadow-xs dark:border-white/10 dark:bg-white/5">
                <div className="border-b border-gray-200 pb-3 dark:border-white/10">
                  <h4 className="text-sm font-semibold text-gray-900 dark:text-white">
                    Streams
                  </h4>
                  <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
                    Codec, FPS, Auflösung und Qualität je Stream.
                  </p>
                </div>

                <div className="mt-4 space-y-4">
                  {streams.length === 0 ? (
                    <p className="text-sm text-gray-500 dark:text-gray-400">
                      Keine Streams gefunden.
                    </p>
                  ) : (
                    streams.map((stream, index) => (
                      <div
                        key={stream.index}
                        className="rounded-lg border border-gray-200 p-4 dark:border-white/10"
                      >
                        <div className="mb-4 flex items-center justify-between gap-3">
                          <div>
                            <h5 className="text-sm font-semibold text-gray-900 dark:text-white">
                              {`Stream ${index + 1}`}
                            </h5>
                            <p className="text-xs text-gray-500 dark:text-gray-400">
                              Index: {stream.index}
                            </p>
                          </div>
                        </div>

                        <div className="grid grid-cols-1 gap-4 sm:grid-cols-6">
                          <input
                            type="hidden"
                            name={`streamIndex-${index}`}
                            value={stream.index}
                          />

                          <div className="sm:col-span-2">
                            <label className="block text-sm/6 font-medium text-gray-900 dark:text-white">
                              Codec
                            </label>
                            <div className="mt-2">
                              <input
                                name={`streamCodec-${index}`}
                                type="text"
                                defaultValue={stream.codec}
                                className={inputClassName()}
                              />
                            </div>
                          </div>

                          <div className="sm:col-span-1">
                            <label className="block text-sm/6 font-medium text-gray-900 dark:text-white">
                              FPS
                            </label>
                            <div className="mt-2">
                              <input
                                name={`streamFps-${index}`}
                                type="number"
                                min="0"
                                step="1"
                                defaultValue={stream.fps ?? ''}
                                className={inputClassName()}
                              />
                            </div>
                          </div>

                          <div className="sm:col-span-1">
                            <label className="block text-sm/6 font-medium text-gray-900 dark:text-white">
                              JPEG-Qualität
                            </label>
                            <div className="mt-2">
                              <input
                                name={`streamJPEGQuality-${index}`}
                                type="number"
                                min="0"
                                step="1"
                                defaultValue={stream.jPEGQuality ?? ''}
                                className={inputClassName()}
                              />
                            </div>
                          </div>

                          <div className="sm:col-span-1">
                            <label className="block text-sm/6 font-medium text-gray-900 dark:text-white">
                              Qualität
                            </label>
                            <div className="mt-2">
                              <input
                                name={`streamQuality-${index}`}
                                type="number"
                                min="0"
                                step="1"
                                defaultValue={stream.quality ?? ''}
                                className={inputClassName()}
                              />
                            </div>
                          </div>

                          <div className="sm:col-span-2">
                            <label className="block text-sm/6 font-medium text-gray-900 dark:text-white">
                              Auflösung
                            </label>
                            <div className="mt-2">
                              <input
                                name={`streamResolution-${index}`}
                                type="text"
                                defaultValue={stream.resolution}
                                className={inputClassName()}
                              />
                            </div>
                          </div>
                        </div>
                      </div>
                    ))
                  )}
                </div>
              </section>
            </div>
          )}
        </div>

        <div className="flex justify-end gap-x-3 border-t border-gray-200 px-4 py-4 sm:px-6 dark:border-white/10">
          <Button
            type="button"
            variant="secondary"
            color="gray"
            disabled={isSaving}
            onClick={() => setOpen(false)}
          >
            Abbrechen
          </Button>

          <Button
            type="submit"
            color="indigo"
            isLoading={isSaving}
            disabled={isLoading || !camera}
            leadingIcon={<CheckIcon aria-hidden="true" className="size-4" />}
          >
            Kamera speichern
          </Button>
        </div>
      </form>
    </Modal>
  )
}