import { useEffect, useLayoutEffect, useRef, type CSSProperties, type JSX } from 'react'
import { useAudioStore } from '../stores/audioStore'
import { useSettingsStore } from '../stores/settingsStore'
import { useThemeStore, PRESETS, PRESET_IDS } from '../stores/themeStore'
import type { ScopeKind } from '../../types/scope'
import { SCOPE_KINDS } from '../../types/scope'

const SCOPE_LABELS: Record<ScopeKind, string> = {
  spectrum: 'Spectrum',
  oscilloscope: 'Oscilloscope',
  vectorscope: 'Vectorscope',
  spectrogram: 'Spectrogram',
  vumeter: 'VU Meter',
  lufsmeter: 'LUFS Meter',
  waveform: 'Waveform',
}

interface BottomBarProps {
  onClose: () => void
  onHeightChange?: (height: number) => void
}

export default function BottomBar({ onClose, onHeightChange }: BottomBarProps): JSX.Element {
  const rootRef = useRef<HTMLDivElement | null>(null)

  const hiddenScopes = useSettingsStore((s) => s.hiddenScopes)
  const toggleScope = useSettingsStore((s) => s.toggleScope)
  const { presetId, accent, setPreset, setCustomAccent, customAccent } = useThemeStore()

  const {
    systemSources,
    devices,
    selectedSystemSourceId,
    selectedDeviceId,
    captureMode,
    isCapturing,
    captureStatus,
    captureError,
    inputGainDb,
    refreshSystemSources,
    refreshDevices,
    refreshBackendSupport,
    selectSystemSource,
    selectDevice,
    startCapture,
    setInputGain,
  } = useAudioStore()

  useEffect(() => {
    void refreshBackendSupport()
    void refreshSystemSources()
    void refreshDevices()
  }, [refreshBackendSupport, refreshSystemSources, refreshDevices])

  useLayoutEffect(() => {
    if (!onHeightChange || !rootRef.current) return

    const rootElement = rootRef.current
    let frameId = 0

    const reportHeight = (): void => {
      cancelAnimationFrame(frameId)
      frameId = requestAnimationFrame(() => {
        onHeightChange(Math.ceil(rootElement.getBoundingClientRect().height))
      })
    }

    reportHeight()

    const resizeObserver = new ResizeObserver(() => {
      reportHeight()
    })

    resizeObserver.observe(rootElement)

    return () => {
      cancelAnimationFrame(frameId)
      resizeObserver.disconnect()
    }
  }, [onHeightChange])

  const handleSourceChange = async (value: string): Promise<void> => {
    if (value.startsWith('system:')) {
      const sourceId = value.slice('system:'.length)
      await selectSystemSource(sourceId)
      await startCapture()
      return
    }

    if (value.startsWith('device:')) {
      const deviceId = value.slice('device:'.length)
      await selectDevice(deviceId)
      await startCapture()
    }
  }

  const selectedSourceValue = captureMode === 'system'
    ? `system:${selectedSystemSourceId ?? systemSources[0]?.id ?? '__default_system_output__'}`
    : `device:${selectedDeviceId ?? ''}`

  const visibleSystemSources = systemSources.length
    ? systemSources
    : [{ id: '__default_system_output__', label: 'System Output', kind: 'system', isDefault: true }]

  const showInputDevices = devices.length > 0

  const indicatorLabel = isCapturing
    ? 'Capturing'
    : captureStatus === 'connecting'
      ? 'Connecting'
      : captureStatus === 'error'
        ? 'Capture Failed'
        : 'Idle'

  const trimPercent = Math.min(100, Math.max(0, ((inputGainDb + 12) / 24) * 100))

  return (
    <div className="bottom-bar" ref={rootRef}>
      <div className="bottom-bar__rail" aria-label="Global settings">
        <div className="bottom-bar__rail-content">
          <section className="bottom-bar__section bottom-bar__section--modules">
            <div className="bottom-bar__section-title">Modules</div>
            <div className="bottom-bar__section-body">
              <div className="bottom-bar__inline bottom-bar__inline--chips">
                {SCOPE_KINDS.map((kind) => {
                  const active = !hiddenScopes.has(kind)
                  return (
                    <button
                      key={kind}
                      type="button"
                      className={`settings-chip ${active ? 'is-active' : ''}`.trim()}
                      onClick={() => toggleScope(kind)}
                      title={SCOPE_LABELS[kind]}
                    >
                      {SCOPE_LABELS[kind]}
                    </button>
                  )
                })}
              </div>
            </div>
          </section>

          <div className="bottom-bar__divider" />

          <section className="bottom-bar__section bottom-bar__section--theme">
            <div className="bottom-bar__section-title">Theme</div>
            <div className="bottom-bar__section-body">
              <div className="bottom-bar__inline bottom-bar__inline--theme">
                {PRESET_IDS.map((id) => {
                  const preset = PRESETS[id]
                  const active = presetId === id && !customAccent
                  return (
                    <button
                      key={id}
                      type="button"
                      className={`settings-swatch ${active ? 'is-active' : ''}`.trim()}
                      style={{ '--swatch-color': preset.accent } as CSSProperties}
                      onClick={() => setPreset(id)}
                      title={preset.name}
                      aria-label={preset.name}
                    />
                  )
                })}
                <input
                  className="settings-accent-input"
                  type="color"
                  value={accent}
                  onChange={(event) => setCustomAccent(event.target.value)}
                  title="Custom accent color"
                />
                {customAccent && (
                  <button
                    type="button"
                    className="settings-chip"
                    onClick={() => setCustomAccent(null)}
                  >
                    Reset
                  </button>
                )}
              </div>
            </div>
          </section>

          <div className="bottom-bar__divider" />

          <section className="bottom-bar__section bottom-bar__section--source">
            <div className="bottom-bar__section-title">Audio Source</div>
            <div className="bottom-bar__section-body">
              <div className="bottom-bar__inline">
                <select
                  className="settings-control__select"
                  value={selectedSourceValue}
                  onChange={(event) => {
                    void handleSourceChange(event.target.value)
                  }}
                >
                  <optgroup label="Output Devices">
                    {visibleSystemSources.map((source) => (
                      <option key={source.id} value={`system:${source.id}`}>
                        {source.isDefault ? `${source.label} (Default)` : source.label}
                      </option>
                    ))}
                  </optgroup>
                  {showInputDevices ? (
                    <optgroup label="Input Devices">
                      {devices.map((device) => (
                        <option key={device.deviceId} value={`device:${device.deviceId}`}>
                          {device.label || `Input ${device.deviceId.slice(0, 8)}`}
                        </option>
                      ))}
                    </optgroup>
                  ) : null}
                </select>

                <div className={`settings-status-pill is-${captureStatus}`.trim()}>
                  <span className="settings-status-pill__dot" />
                  <span>{indicatorLabel}</span>
                </div>
              </div>

              {captureError ? (
                <div className="settings-error-text bottom-bar__error-text">{captureError}</div>
              ) : null}
            </div>
          </section>

          <div className="bottom-bar__divider" />

          <section className="bottom-bar__section bottom-bar__section--trim">
            <div className="bottom-bar__section-title">Trim</div>
            <div className="bottom-bar__section-body">
              <div className="bottom-bar__inline">
                <span className="bottom-bar__trim-value">
                  {inputGainDb > 0 ? '+' : ''}{inputGainDb.toFixed(1)}dB
                </span>
                <input
                  className="settings-control__range bottom-bar__trim-slider"
                  type="range"
                  min={-12}
                  max={12}
                  step={0.5}
                  value={inputGainDb}
                  style={{ '--range-percent': `${trimPercent}%` } as CSSProperties}
                  onChange={(event) => setInputGain(Number(event.target.value))}
                  onDoubleClick={() => setInputGain(0)}
                />
              </div>
            </div>
          </section>
        </div>
      </div>

      <div className="bottom-bar__actions">
        <button
          type="button"
          className="settings-panel__close bottom-bar__close"
          onClick={onClose}
        >
          Close
        </button>
      </div>
    </div>
  )
}
