/**
 * Page de rapport de correction — Sprint 3.6b.
 *
 * Sections toujours visibles : score + jauge, revelation, diagnostic, conseil_nclc.
 * Sections conditionnelles via isSectionVisible(plan, section) :
 *   detailed_report → criteres (avec exemple/suggestion/astuce/codes)
 *   tips            → exercices, modele
 *
 * Les exercices et la production modèle peuvent être dans l'état `pending`
 * (jobs fire-and-forget côté backend — cf. correctionController 3.6a) ou
 * `error` : JobStatusFallback affiche le message approprié (refresh manuel
 * uniquement ; polling traqué en FTD-24).
 *
 * SEC-05 : textes IA rendus via react-markdown, jamais dangerouslySetInnerHTML.
 * Règle D : isSectionVisible() obligatoire — jamais if (plan === 'xxx').
 * Règle H : logique de floutage dans entities/report/lib.ts.
 */

import { useEffect } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { Lock } from 'lucide-react'
import { usePlan } from '@/features/dashboard/hooks/usePlan'
import { isSectionVisible, groupErreursByCritere, critereCodeFromNom } from '@/entities/report/lib'
import type { Report } from '@/entities/report/types'
import { useRapport } from '../hooks/useRapport'
import { useSimulation } from '../hooks/useSimulation'
import { Card } from '@/shared/ui/Card'
import { Button } from '@/shared/ui/Button'
import { ScoreHero } from '../components/rapport/ScoreHero'
import { RevelationCards } from '../components/rapport/RevelationCards'
import { DiagnosticCallout } from '../components/rapport/DiagnosticCallout'
import { CritereCard } from '../components/rapport/CritereCard'
import { ConseilNclcCallout } from '../components/rapport/ConseilNclcCallout'
import { ExerciceInteractive } from '../components/rapport/ExerciceInteractive'
import { ProductionModeleSection } from '../components/rapport/ProductionModeleSection'
import { JobStatusFallback } from '../components/rapport/JobStatusFallback'

function isReportNotReady(err: unknown): boolean {
  return (
    typeof err === 'object' &&
    err !== null &&
    'code' in err &&
    (err as { code: unknown }).code === 'REPORT_NOT_READY'
  )
}

// ── Floutage section ────────────────────────────────────────────────────

const PLACEHOLDER_WIDTHS = ['w-3/4', 'w-full', 'w-3/5', 'w-4/5'] as const

function BlurredSection({
  visible,
  onUpgrade,
  children,
}: {
  visible: boolean
  onUpgrade: () => void
  children: React.ReactNode
}) {
  if (visible) return <>{children}</>
  return (
    <div className="relative min-h-[120px] overflow-hidden rounded-lg border border-line bg-canvas-2">
      <div className="space-y-2 p-4 opacity-25 blur-sm" aria-hidden="true">
        {PLACEHOLDER_WIDTHS.map((w, i) => (
          <div key={i} className={`h-3 rounded bg-ink-4 ${w}`} />
        ))}
      </div>
      <div className="absolute inset-0 flex flex-col items-center justify-center gap-3 px-4">
        <Lock className="size-5 text-ink-4" aria-hidden="true" />
        <p className="text-sm font-medium text-ink-2">Disponible en Standard</p>
        <Button variant="upgrade" size="sm" onClick={onUpgrade}>
          Passer en Standard
        </Button>
      </div>
    </div>
  )
}

// ── Squelette ───────────────────────────────────────────────────────────

function RapportSkeleton() {
  return (
    <div className="space-y-4" aria-busy="true" aria-label="Chargement du rapport…">
      <div className="h-40 animate-pulse rounded-lg bg-canvas-2" />
      <div className="h-28 animate-pulse rounded-lg bg-canvas-2" />
      <div className="h-32 animate-pulse rounded-lg bg-canvas-2" />
      <div className="h-48 animate-pulse rounded-lg bg-canvas-2" />
    </div>
  )
}

// ── Sections thématiques ─────────────────────────────────────────────────

function CriteresSection({ rapport }: { rapport: Report }) {
  const grouped = groupErreursByCritere(rapport.erreurs_codes)

  return (
    <section aria-label="Détail par critère">
      <h2 className="mb-3 text-base font-semibold text-ink-1">Détail par critère</h2>
      <div className="space-y-3">
        {rapport.criteres.map((c) => {
          const code = critereCodeFromNom(c.nom)
          const codes = code ? grouped[code] : []
          return <CritereCard key={c.nom} critere={c} erreursCodes={codes} />
        })}
      </div>
    </section>
  )
}

function ExercicesSection({ rapport }: { rapport: Report }) {
  if (rapport.exercices_status !== 'ready' || !rapport.exercices) {
    return (
      <section aria-label="Exercices personnalisés">
        <h2 className="mb-3 text-base font-semibold text-ink-1">Mes exercices personnalisés</h2>
        <JobStatusFallback
          status={rapport.exercices_status}
          pendingLabel="Génération des exercices en cours…"
          errorLabel="Exercices indisponibles. Réessayez plus tard."
        />
      </section>
    )
  }

  return (
    <section aria-label="Exercices personnalisés">
      <h2 className="mb-3 text-base font-semibold text-ink-1">Mes exercices personnalisés</h2>
      <div className="space-y-3">
        {rapport.exercices.map((ex, i) => (
          <ExerciceInteractive key={`${ex.theme}-${i}`} exercice={ex} />
        ))}
      </div>
    </section>
  )
}

function ModeleSection({ rapport }: { rapport: Report }) {
  if (rapport.modele_status !== 'ready' || !rapport.modele) {
    return (
      <section aria-label="Production modèle">
        <h2 className="mb-3 text-base font-semibold text-ink-1">Version restructurée NCLC 9+</h2>
        <JobStatusFallback
          status={rapport.modele_status}
          pendingLabel="Production modèle en cours de génération…"
          errorLabel="Production modèle indisponible. Réessayez plus tard."
        />
      </section>
    )
  }

  return (
    <section aria-label="Production modèle">
      <h2 className="mb-3 text-base font-semibold text-ink-1">Version restructurée NCLC 9+</h2>
      <ProductionModeleSection modele={rapport.modele} />
    </section>
  )
}

// ── Page principale ──────────────────────────────────────────────────────

export function RapportPage() {
  const { id = '' } = useParams<{ id: string }>()
  const navigate = useNavigate()

  const { rapport, isLoading, isError, error } = useRapport(id)
  const isInProgress = isError && isReportNotReady(error)

  const { reset } = useSimulation()

  const { data: planData, isLoading: isPlanLoading, isError: isPlanError } = usePlan()

  // FTD-21 — si la simulation n'est pas encore corrigée, rediriger vers /simulation/ee.
  useEffect(() => {
    if (isInProgress) {
      navigate('/simulation/ee', { replace: true })
    }
  }, [isInProgress, navigate])

  const onUpgrade = () => navigate('/plan')

  // Quitter le rapport proprement : reset du flow (step, production, mutations)
  // avant de naviguer — sinon step='done' resterait sticky et empêcherait le
  // retour au TaskSelector ou à /sujets.
  function goToSimulations() {
    reset()
    navigate('/simulation/ee')
  }

  return (
    <main className="mx-auto max-w-3xl space-y-6 px-4 py-6">
      {/* Breadcrumb */}
      <nav aria-label="Fil d'Ariane" className="flex items-center gap-1.5 text-sm text-ink-4">
        <button
          type="button"
          onClick={goToSimulations}
          className="transition-colors duration-150 hover:text-ink-2"
        >
          Simulations
        </button>
        <span aria-hidden="true">›</span>
        <span aria-current="page" className="text-ink-2">
          Rapport
        </span>
      </nav>

      {(isLoading || isPlanLoading) && <RapportSkeleton />}

      {isInProgress && (
        <p className="text-center text-sm text-ink-4" aria-live="polite">
          Votre simulation est en cours.
        </p>
      )}

      {(isError || isPlanError) && !isInProgress && !isLoading && !isPlanLoading && (
        <Card variant="default" className="border-l-4 border-l-danger p-4">
          <div role="alert" className="space-y-3">
            <p className="text-sm text-danger">
              Impossible de charger ce rapport. Réessayez dans quelques instants.
            </p>
            <Button variant="secondary" size="sm" onClick={() => navigate('/simulation/ee')}>
              Retour aux simulations
            </Button>
          </div>
        </Card>
      )}

      {rapport && planData && (
        <>
          <ScoreHero score={rapport.score} nclc={rapport.nclc} nclcCible={rapport.nclc_cible} />

          <RevelationCards revelation={rapport.revelation} />

          <DiagnosticCallout diagnostic={rapport.diagnostic} />

          <BlurredSection
            visible={isSectionVisible(planData.plan, 'criteres')}
            onUpgrade={onUpgrade}
          >
            <CriteresSection rapport={rapport} />
          </BlurredSection>

          <ConseilNclcCallout conseil={rapport.conseil_nclc} />

          <BlurredSection
            visible={isSectionVisible(planData.plan, 'exercices')}
            onUpgrade={onUpgrade}
          >
            <ExercicesSection rapport={rapport} />
          </BlurredSection>

          <BlurredSection visible={isSectionVisible(planData.plan, 'modele')} onUpgrade={onUpgrade}>
            <ModeleSection rapport={rapport} />
          </BlurredSection>

          {/* Action de sortie — reset + nouvelle simulation */}
          <div className="flex justify-center pt-4">
            <Button variant="primary" onClick={goToSimulations}>
              Nouvelle simulation
            </Button>
          </div>
        </>
      )}
    </main>
  )
}
