/**
 * Composant d'enregistrement audio pour les productions orales —
 * Sprint 4c-1, simplifié au Sprint 4c-3.
 *
 * Encapsule `useAudioRecorder` côté UI : timer montant MM:SS, indicateur
 * visuel d'enregistrement, garde-fou minimum 30 s, bouton de téléchargement
 * local de l'audio (le backend ne stocke aucun audio).
 *
 * Le streaming chunk-par-chunk a été retiré au Sprint 4c-3 : l'audio est
 * envoyé entier au backend après stop, le backend appelle Gemini batch pour
 * transcrire. `useAudioRecorder.subscribeChunks` reste exposé côté hook
 * pour un usage futur (ex. réactivation Deepgram live).
 */

import { useEffect } from 'react'
import { Download, Mic, MicOff, Square } from 'lucide-react'
import { Button } from '@/shared/ui/Button'
import { formatTimer } from '../lib/simulationConfig'
import { useAudioRecorder } from '../hooks/useAudioRecorder'
import { RecordingTimeline } from './RecordingTimeline'
import { RecordingWaveform } from './RecordingWaveform'

interface Props {
  /** Durée minimale (s) avant que la soumission soit autorisée. */
  minSeconds: number
  /**
   * Sprint 4b.3 — durée maximale recommandée (s). À l'atteinte, le hook
   * arrête automatiquement l'enregistrement et l'`onSubmit` est déclenché
   * via le chemin existant (status='stopped' → useEffect onSubmit).
   */
  maxSeconds?: number
  /** Notification optionnelle quand `maxSeconds` est atteint. */
  onMaxReached?: () => void
  /** Nom de fichier proposé au téléchargement local (sans extension). */
  downloadFilename: string
  /** Appelé au clic « Arrêter et soumettre » avec le blob final + son MIME. */
  onSubmit: (audioBlob: Blob, audioMimeType: string | null) => void
  onCancel: () => void
  /** Initialisé à true → l'utilisateur démarre l'enregistrement automatiquement
   *  au mount. Sinon, un bouton « Démarrer » est affiché. */
  autoStart?: boolean
  /**
   * Sprint 4c-3 — désactive les contrôles tant qu'une soumission est en
   * cours côté parent (transcription + correction backend ~30-60 s).
   */
  disabled?: boolean
}

export function AudioRecorder({
  minSeconds,
  maxSeconds,
  onMaxReached,
  downloadFilename,
  onSubmit,
  onCancel,
  autoStart = true,
  disabled = false,
}: Props) {
  const recorder = useAudioRecorder({ maxSeconds, onMaxReached })

  // Auto-start au mount si demandé. Pas de dépendance sur `recorder.start`
  // pour éviter les re-runs au changement d'identité de la fonction.
  useEffect(() => {
    if (!autoStart) return
    void recorder.start()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [autoStart])

  const isRecording = recorder.status === 'recording'
  const isStopped = recorder.status === 'stopped'
  const remaining = Math.max(0, minSeconds - recorder.elapsedSeconds)
  const submitEnabled = isRecording && remaining === 0

  function handleSubmitClick() {
    recorder.stop()
  }

  // Quand le recorder passe en 'stopped', on remonte le blob au parent.
  useEffect(() => {
    if (recorder.status === 'stopped' && recorder.audioBlob) {
      onSubmit(recorder.audioBlob, recorder.audioMimeType)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [recorder.status, recorder.audioBlob])

  if (recorder.status === 'error') {
    return (
      <div
        role="alert"
        className="rounded-lg border border-danger/40 bg-danger-soft px-4 py-3 text-sm text-danger"
      >
        <div className="flex items-start gap-2">
          <MicOff className="mt-0.5 size-4 shrink-0" aria-hidden="true" />
          <div className="flex-1">
            <p className="font-medium">{recorder.error ?? 'Erreur audio.'}</p>
            {recorder.permissionDenied && (
              <p className="mt-1 text-xs">
                Vérifiez que le site a l'autorisation d'utiliser le micro dans les réglages du
                navigateur, puis réessayez.
              </p>
            )}
          </div>
        </div>
        <div className="mt-3 flex gap-2">
          <Button variant="secondary" size="sm" onClick={() => void recorder.start()}>
            Réessayer
          </Button>
          <Button variant="ghost" size="sm" onClick={onCancel}>
            Annuler
          </Button>
        </div>
      </div>
    )
  }

  return (
    <div className="rounded-lg border border-border bg-surface p-4">
      <div className="flex items-center gap-3">
        <span
          aria-hidden="true"
          className={
            isRecording
              ? 'inline-block size-3 animate-pulse rounded-pill bg-danger'
              : 'inline-block size-3 rounded-pill bg-ink-tertiary/40'
          }
        />
        <span className="text-sm font-medium text-ink-primary">
          {recorder.status === 'requesting' && 'Autorisation du micro…'}
          {isRecording && 'Enregistrement actif'}
          {isStopped && 'Enregistrement terminé'}
          {recorder.status === 'idle' && 'Prêt'}
        </span>
        <span
          className="ml-auto font-mono text-xl tabular-nums text-ink-primary"
          aria-live="polite"
        >
          {formatTimer(recorder.elapsedSeconds)}
        </span>
      </div>

      {isRecording && (
        <div className="mt-3">
          <RecordingWaveform stream={recorder.mediaStream} />
        </div>
      )}

      {maxSeconds && (isRecording || isStopped) && (
        <div className="mt-3">
          <RecordingTimeline elapsedSeconds={recorder.elapsedSeconds} maxSeconds={maxSeconds} />
        </div>
      )}

      {isRecording && remaining > 0 && (
        <p className="mt-3 text-xs text-ink-secondary">
          Minimum 30 secondes requis ({remaining} s restantes).
        </p>
      )}

      <div className="mt-4 flex flex-wrap items-center gap-2">
        {isRecording && (
          <>
            <Button
              variant="primary"
              size="sm"
              icon={<Square className="size-4" aria-hidden="true" />}
              onClick={handleSubmitClick}
              disabled={!submitEnabled || disabled}
            >
              {submitEnabled ? 'Arrêter et soumettre' : `Arrêter et soumettre (${remaining}s)`}
            </Button>
            <Button variant="ghost" size="sm" onClick={onCancel} disabled={disabled}>
              Annuler
            </Button>
          </>
        )}

        {recorder.status === 'idle' && (
          <Button
            variant="primary"
            size="sm"
            icon={<Mic className="size-4" aria-hidden="true" />}
            onClick={() => void recorder.start()}
          >
            Démarrer l'enregistrement
          </Button>
        )}

        {isStopped && (
          <Button
            variant="secondary"
            size="sm"
            icon={<Download className="size-4" aria-hidden="true" />}
            onClick={() => recorder.downloadAudio(`${downloadFilename}.webm`)}
          >
            Télécharger l'audio
          </Button>
        )}
      </div>
    </div>
  )
}
