/**
 * Page /simulation/eo/t1/live/dialogue — phase de dialogue live T1 (Sprint 7b).
 *
 * Démarre la session WS au mount, pilote l'UI selon l'état machine T1, affiche le
 * timer 3:00 et l'indicateur d'état. Spécificité T1 : l'examinateur peut
 * INTERROMPRE le monologue de façon NON DÉTERMINISTE (état `interrupted`) — l'UI
 * ne suppose JAMAIS qu'une relance suit. À la fin (REPORT_READY), écran terminal
 * avec « Télécharger l'audio » + « Voir le rapport ».
 */

import { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { Mic, Volume2, Download, FileText, Loader2 } from 'lucide-react'
import { Button } from '@/shared/ui/Button'
import { Card } from '@/shared/ui/Card'
import { T1SpeakingIndicator } from '../components/T1SpeakingIndicator'
import { useT1LiveSession } from '../hooks/useT1LiveSession'

const DIALOGUE_SECONDS = 180 // 3:00

function formatMmSs(totalSeconds: number): string {
  const remaining = Math.max(0, totalSeconds)
  const m = Math.floor(remaining / 60)
  const s = remaining % 60
  return `${m}:${s.toString().padStart(2, '0')}`
}

export function T1DialoguePage() {
  const navigate = useNavigate()
  const [autoStarted, setAutoStarted] = useState(false)

  const session = useT1LiveSession()

  // Démarrer le dialogue automatiquement au mount (la prépa est déjà finie).
  useEffect(() => {
    if (autoStarted) return
    setAutoStarted(true)
    void session.startDialogue()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [autoStarted])

  const remaining = DIALOGUE_SECONDS - session.elapsedSeconds
  const stateLabel = (() => {
    switch (session.state) {
      case 'idle':
      case 'connecting':
        return 'Connexion à l’examinateur…'
      case 'presenting':
        return 'À vous — présentez-vous.'
      case 'interrupted':
        return 'L’examinateur vous interrompt — répondez-lui.'
      case 'processing':
        return 'Évaluation en cours…'
      case 'ended':
        return 'Session terminée.'
      case 'error':
        return 'Erreur.'
      case 'preparing':
        return 'Préparation…'
    }
  })()

  function handleDownload() {
    const blob = session.recording.exportWAV()
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `expria-t1-${new Date().toISOString().slice(0, 10)}.wav`
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
    URL.revokeObjectURL(url)
  }

  function handleViewReport() {
    if (!session.simulationId) return
    navigate(`/rapport/${session.simulationId}`)
  }

  function handleRestart() {
    navigate('/simulation/eo/t1/live/preparation')
  }

  // Abandon : ferme la session sans évaluation (cancelDialogue ne déclenche ni
  // correction ni persistance), puis sortie du flux.
  function handleCancel() {
    session.cancelDialogue()
    navigate('/simulation/eo')
  }

  // « Annuler » / « Terminer » n'ont de sens que pendant la session active
  // (connexion, présentation ou interruption), pas en évaluation.
  const canCancel =
    session.state === 'connecting' ||
    session.state === 'presenting' ||
    session.state === 'interrupted'

  // ── État terminal : rapport prêt ─────────────────────────────────────────
  if (session.state === 'ended') {
    return (
      <div className="mx-auto w-full max-w-[1100px] px-5 py-6 lg:px-9 lg:py-9">
        <main className="mx-auto max-w-2xl space-y-5">
          <h2 className="text-lg font-semibold text-ink-primary">Session terminée</h2>
          <Card variant="default" className="space-y-3 p-5">
            <p className="text-sm text-ink-primary">
              Votre présentation a été évaluée. Vous pouvez télécharger l'enregistrement audio avant
              de consulter le rapport.
            </p>
            <p className="text-xs text-ink-secondary">
              Durée enregistrée :{' '}
              <span className="font-semibold tabular-nums text-ink-primary">
                {session.recording.durationSeconds.toFixed(1)} s
              </span>
            </p>
          </Card>
          <div className="flex flex-wrap items-center gap-3">
            <Button
              variant="secondary"
              icon={<Download className="size-4" aria-hidden="true" />}
              onClick={handleDownload}
              disabled={session.recording.durationSeconds === 0}
            >
              Télécharger l'audio
            </Button>
            <Button
              variant="primary"
              icon={<FileText className="size-4" aria-hidden="true" />}
              onClick={handleViewReport}
              disabled={!session.simulationId}
            >
              Voir le rapport
            </Button>
          </div>
        </main>
      </div>
    )
  }

  // ── État erreur ──────────────────────────────────────────────────────────
  if (session.state === 'error') {
    return (
      <div className="mx-auto w-full max-w-[1100px] px-5 py-6 lg:px-9 lg:py-9">
        <main className="mx-auto max-w-2xl space-y-5">
          <h2 className="text-lg font-semibold text-ink-primary">Erreur</h2>
          <div
            role="alert"
            className="rounded-md border border-danger/40 bg-danger-soft px-4 py-3 text-sm text-danger"
          >
            {session.errorMessage ?? 'Une erreur est survenue.'}
          </div>
          <div className="flex gap-3">
            <Button variant="secondary" onClick={handleRestart}>
              Recommencer
            </Button>
          </div>
        </main>
      </div>
    )
  }

  // ── État dialogue actif ──────────────────────────────────────────────────
  return (
    <div className="mx-auto w-full max-w-[1100px] px-5 py-6 lg:px-9 lg:py-9">
      <main className="mx-auto max-w-2xl space-y-5">
        <div className="flex items-center justify-between">
          <h2 className="text-lg font-semibold text-ink-primary">Présentation en cours</h2>
          <span
            className="rounded-full border border-border bg-surface px-3 py-1 text-sm font-semibold tabular-nums text-ink-primary"
            aria-label="Temps restant de présentation"
          >
            {formatMmSs(remaining)}
          </span>
        </div>

        {session.warning && (
          <div
            role="status"
            className="rounded-md border border-warning/40 bg-warning-soft px-3 py-2 text-sm text-ink-primary"
          >
            ⏱ 30 secondes restantes.
          </div>
        )}

        <Card variant="default" className="space-y-4 p-5">
          <div className="flex items-center gap-3">
            {session.state === 'processing' ? (
              <Loader2 className="size-5 animate-spin text-brand-text" aria-hidden="true" />
            ) : session.state === 'interrupted' ? (
              <Volume2 className="size-5 text-brand-text" aria-hidden="true" />
            ) : (
              <Mic
                className={
                  session.state === 'presenting'
                    ? 'size-5 text-success'
                    : 'size-5 text-ink-secondary'
                }
                aria-hidden="true"
              />
            )}
            <p className="text-sm font-semibold text-ink-primary">{stateLabel}</p>
          </div>
          {/* Indicateur : 'presenting' = amplitude micro réelle (analyser lu par
              ref en rAF) ; 'interrupted' = animation décorative (uplink coupé). */}
          {canCancel && (
            <T1SpeakingIndicator analyserRef={session.analyserRef} state={session.state} />
          )}
          <p className="text-xs text-ink-secondary">
            Présentez-vous naturellement. L'examinateur peut vous interrompre à tout moment.
          </p>
        </Card>

        <div className="flex items-center justify-center gap-3">
          {canCancel && (
            <Button
              variant="ghost"
              className="text-danger hover:bg-danger-soft hover:text-danger"
              onClick={handleCancel}
              title="Abandonner sans générer de rapport"
            >
              Annuler
            </Button>
          )}
          <Button
            variant="secondary"
            onClick={() => session.endDialogue()}
            disabled={session.state === 'processing'}
          >
            Terminer
          </Button>
        </div>
        <p className="text-center text-xs text-ink-tertiary">
          « Annuler » abandonne la session sans rapport. « Terminer » lance l'évaluation.
        </p>
      </main>
    </div>
  )
}
