import type { PoseSettings } from './types'
import { playSound, SFX_BUTTON_DEFAULT } from './lib/sounds'
import './Settings.css'

const MODELS = [
  { label: 'Lite', value: 'pose_landmarker_lite' },
  { label: 'Full', value: 'pose_landmarker_full' },
  { label: 'Heavy', value: 'pose_landmarker_heavy' },
]

interface DifficultyOption {
  label: string
  meter: number
}

interface SongOption {
  id: string
  title: string
}

interface Props {
  settings: PoseSettings
  onChange: (s: PoseSettings) => void
  open: boolean
  onToggle: () => void
  fps: number
  songs?: SongOption[]
  selectedSong?: string
  onSongChange?: (songId: string) => void
  difficulties?: DifficultyOption[]
  selectedDifficulty?: string
  onDifficultyChange?: (difficulty: string) => void
}

export function Settings({ settings, onChange, open, onToggle, fps, songs, selectedSong, onSongChange, difficulties, selectedDifficulty, onDifficultyChange }: Props) {
  const update = (partial: Partial<PoseSettings>) =>
    onChange({ ...settings, ...partial })

  return (
    <>
      <button
        type="button"
        className="settings-toggle"
        onClick={() => {
          playSound(SFX_BUTTON_DEFAULT)
          onToggle()
        }}
      >
        ⚙
      </button>

      {open && (
        <div className="settings-panel">
          <h3>Pose Detection Settings</h3>

          <div className="fps-display">MediaPipe FPS: <span className="value">{fps}</span></div>

          <button
            type="button"
            className="fullscreen-btn"
            onClick={() => {
              playSound(SFX_BUTTON_DEFAULT)
              if (document.fullscreenElement) document.exitFullscreen()
              else document.documentElement.requestFullscreen().catch(() => {})
            }}
          >
            {document.fullscreenElement ? 'Exit Fullscreen' : 'Fullscreen'}
          </button>

          <label className="toggle-label">
            <input
              type="checkbox"
              checked={settings.showDebug}
              onChange={(e) => update({ showDebug: e.target.checked })}
            />
            Show Debug
          </label>

          {songs && songs.length > 0 && (
            <label>
              Song
              <select
                value={selectedSong}
                onChange={(e) => onSongChange?.(e.target.value)}
              >
                {songs.map((s) => (
                  <option key={s.id} value={s.id}>
                    {s.title}
                  </option>
                ))}
              </select>
            </label>
          )}

          {difficulties && difficulties.length > 0 && (
            <label>
              Difficulty
              <select
                value={selectedDifficulty}
                onChange={(e) => onDifficultyChange?.(e.target.value)}
              >
                {difficulties.map((d) => (
                  <option key={d.label} value={d.label}>
                    {d.label} ({d.meter})
                  </option>
                ))}
              </select>
            </label>
          )}

          <hr className="settings-divider" />

          <label>
            Model
            <select
              value={settings.model}
              onChange={(e) => update({ model: e.target.value })}
            >
              {MODELS.map((m) => (
                <option key={m.value} value={m.value}>
                  {m.label}
                </option>
              ))}
            </select>
          </label>

          <label>
            Delegate
            <select
              value={settings.delegate}
              onChange={(e) => update({ delegate: e.target.value as 'GPU' | 'CPU' })}
            >
              <option value="GPU">GPU</option>
              <option value="CPU">CPU</option>
            </select>
          </label>

          <label>
            Num Poses
            <input
              type="range"
              min={1}
              max={5}
              step={1}
              value={settings.numPoses}
              onChange={(e) => update({ numPoses: Number(e.target.value) })}
            />
            <span className="value">{settings.numPoses}</span>
          </label>

          <label>
            Min Detection Confidence
            <input
              type="range"
              min={0}
              max={1}
              step={0.05}
              value={settings.minDetectionConfidence}
              onChange={(e) =>
                update({ minDetectionConfidence: Number(e.target.value) })
              }
            />
            <span className="value">{settings.minDetectionConfidence.toFixed(2)}</span>
          </label>

          <label>
            Min Tracking Confidence
            <input
              type="range"
              min={0}
              max={1}
              step={0.05}
              value={settings.minTrackingConfidence}
              onChange={(e) =>
                update({ minTrackingConfidence: Number(e.target.value) })
              }
            />
            <span className="value">{settings.minTrackingConfidence.toFixed(2)}</span>
          </label>

          <label>
            Min Presence Confidence
            <input
              type="range"
              min={0}
              max={1}
              step={0.05}
              value={settings.minPresenceConfidence}
              onChange={(e) =>
                update({ minPresenceConfidence: Number(e.target.value) })
              }
            />
            <span className="value">{settings.minPresenceConfidence.toFixed(2)}</span>
          </label>

          <hr className="settings-divider" />
          <h4>Step Detection</h4>

          <label>
            L/R Threshold
            <input
              type="range"
              min={0.05}
              max={0.5}
              step={0.01}
              value={settings.stepThresholdX}
              onChange={(e) => update({ stepThresholdX: Number(e.target.value) })}
            />
            <span className="value">{settings.stepThresholdX.toFixed(2)}</span>
          </label>

          <label>
            F/B Threshold
            <input
              type="range"
              min={0.05}
              max={0.5}
              step={0.01}
              value={settings.stepThresholdZ}
              onChange={(e) => update({ stepThresholdZ: Number(e.target.value) })}
            />
            <span className="value">{settings.stepThresholdZ.toFixed(2)}</span>
          </label>

          <label>
            Reset
            <input
              type="range"
              min={0.02}
              max={0.3}
              step={0.01}
              value={settings.stepReset}
              onChange={(e) => update({ stepReset: Number(e.target.value) })}
            />
            <span className="value">{settings.stepReset.toFixed(2)}</span>
          </label>
        </div>
      )}
    </>
  )
}
