"use client";

import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { startTransition, useEffect, useMemo, useRef, useState } from "react";
import { MandatoryOnboardingGuard } from "@/components/mandatory-onboarding-guard";
import {
  getMandatoryOnboardingPath,
  getDemoSession,
  upsertDemoSession,
  useDemoBrowserState,
} from "@/lib/demo-session-store";
import { formatScenarioDurationLabel } from "@/lib/scenario-utils";
import { createInitialSession } from "@/lib/session-db";
import {
  createBaselineEvaluation,
  formatStatusLabel,
  metricMeta,
  scoreToLevel,
} from "@/lib/types";
import { TRAINING_MESSAGE_MAX_LENGTH } from "@/lib/training";
import type {
  ConversationOutcome,
  ConversationStatus,
  DemoSessionRecord,
  FinalAssessment,
  ScenarioDefinition,
  TurnResponse,
} from "@/lib/types";

type TrainingShellProps = {
  scenario: ScenarioDefinition;
};

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === "object" && value !== null;
}

function extractApiError(payload: unknown) {
  if (!isRecord(payload)) {
    return null;
  }

  return typeof payload.error === "string" && payload.error.trim()
    ? payload.error
    : null;
}

function getFallbackErrorMessage(status: number, fallbackMessage: string) {
  switch (status) {
    case 401:
      return "Votre session a expire. Reconnectez-vous pour continuer.";
    case 403:
      return "Vous n'avez pas acces a cette action.";
    case 404:
      return "La requete n'a pas abouti. Rechargez la page et reessayez.";
    case 409:
      return "Cette session est deja terminee.";
    case 429:
      return "Le service est temporairement sature. Reessayez dans quelques instants.";
    case 502:
    case 503:
    case 504:
      return "Le service IA est temporairement indisponible. Reessayez dans quelques instants.";
    default:
      return fallbackMessage;
  }
}

async function readResponsePayload(response: Response) {
  const rawText = await response.text();

  if (!rawText) {
    return null;
  }

  try {
    return JSON.parse(rawText) as unknown;
  } catch {
    throw new Error(
      response.ok
        ? "Le serveur a renvoye une reponse invalide. Reessayez."
        : getFallbackErrorMessage(response.status, "La requete a echoue."),
    );
  }
}

async function readApiResponse<T>(
  response: Response,
  isExpectedPayload: (payload: unknown) => payload is T,
  fallbackMessage: string,
) {
  const payload = await readResponsePayload(response);

  if (!response.ok || !isExpectedPayload(payload)) {
    throw new Error(
      extractApiError(payload) ??
        getFallbackErrorMessage(response.status, fallbackMessage),
    );
  }

  return payload;
}

function isTurnPayload(payload: unknown): payload is TurnResponse {
  return (
    isRecord(payload) &&
    "assistantMessage" in payload &&
    "liveEvaluation" in payload &&
    "conversationStatus" in payload
  );
}

function isFinalAssessmentPayload(
  payload: unknown,
): payload is { finalAssessment: FinalAssessment } {
  return isRecord(payload) && "finalAssessment" in payload;
}

function createDemoSessionRecord(scenario: ScenarioDefinition): DemoSessionRecord {
  return {
    ...createInitialSession(scenario, crypto.randomUUID(), {
      clientId: "demo-client",
      scenarioTemplateId: scenario.id,
      scenarioVersionId: `${scenario.id}-demo-v1`,
    }),
    scenarioSnapshot: scenario,
  };
}

function persistSession(nextSession: DemoSessionRecord) {
  upsertDemoSession(nextSession);
  return nextSession;
}

export function TrainingShell({ scenario }: TrainingShellProps) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const browserState = useDemoBrowserState();
  const messagesEndRef = useRef<HTMLDivElement | null>(null);
  const [session, setSession] = useState<DemoSessionRecord | null>(null);
  const [draft, setDraft] = useState("");
  const [pending, setPending] = useState(false);
  const [finalizing, setFinalizing] = useState(false);
  const [bootstrapping, setBootstrapping] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [expandedMetricId, setExpandedMetricId] = useState<string | null>(null);

  const sessionId = searchParams.get("session");
  const requiredOnboardingPath = useMemo(
    () => getMandatoryOnboardingPath(browserState.onboarding),
    [browserState.onboarding],
  );

  useEffect(() => {
    let isActive = true;

    function initialize() {
      if (requiredOnboardingPath) {
        setBootstrapping(false);
        return;
      }

      if (session) {
        setBootstrapping(false);
        return;
      }

      setBootstrapping(true);
      setError(null);

      try {
        if (sessionId) {
          const existing = getDemoSession(sessionId);

          if (existing && existing.scenarioId === scenario.id && isActive) {
            setSession(existing);
            setBootstrapping(false);
            return;
          }
        }

        const created = persistSession(createDemoSessionRecord(scenario));

        if (!isActive) {
          return;
        }

        setSession(created);
        setBootstrapping(false);

        startTransition(() => {
          router.replace(`/scenario/${scenario.id}?session=${created.sessionId}`);
        });
      } catch (caughtError) {
        if (!isActive) {
          return;
        }

        setBootstrapping(false);
        setError(
          caughtError instanceof Error
            ? caughtError.message
            : "La session n'a pas pu etre initialisee.",
        );
      }
    }

    initialize();

    return () => {
      isActive = false;
    };
  }, [requiredOnboardingPath, router, scenario, session, sessionId]);

  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
  }, [session?.transcript.length, pending]);

  const latestEvaluation = useMemo(() => {
    if (!session) {
      return createBaselineEvaluation(scenario);
    }

    return session.liveEvaluations.at(-1) ?? createBaselineEvaluation(scenario);
  }, [scenario, session]);
  const hasStartedDiscussion = (session?.userTurns ?? 0) > 0;
  const draftLength = draft.length;
  const trimmedDraftLength = draft.trim().length;
  const isNearMessageLimit = draftLength >= TRAINING_MESSAGE_MAX_LENGTH * 0.85;
  const hasReachedMessageLimit = draftLength >= TRAINING_MESSAGE_MAX_LENGTH;

  async function finalizeCurrentSession(
    currentSession: DemoSessionRecord,
    conversationStatus: ConversationOutcome,
  ) {
    setFinalizing(true);
    setError(null);

    try {
      const response = await fetch("/api/chat/finalize", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          scenario: currentSession.scenarioSnapshot,
          transcript: currentSession.transcript,
          liveEvaluations: currentSession.liveEvaluations,
          currentStatus: currentSession.status,
          conversationStatus,
        }),
      });

      const payload = await readApiResponse(
        response,
        isFinalAssessmentPayload,
        "Impossible de generer le bilan final.",
      );

      const finalizedSession: DemoSessionRecord = persistSession({
        ...currentSession,
        finalAssessment: payload.finalAssessment,
        status: conversationStatus,
        updatedAt: new Date().toISOString(),
      });

      setSession(finalizedSession);

      startTransition(() => {
        router.push(`/report/${finalizedSession.sessionId}`);
      });
    } catch (caughtError) {
      setError(
        caughtError instanceof Error
          ? caughtError.message
          : "Le bilan final n'a pas pu etre genere.",
      );
    } finally {
      setFinalizing(false);
    }
  }

  async function handleSend(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();

    if (!session || pending || finalizing || session.status !== "ongoing") {
      return;
    }

    const userMessage = draft.trim();
    if (userMessage.length > TRAINING_MESSAGE_MAX_LENGTH) {
      setError(
        `Votre message depasse la limite de ${TRAINING_MESSAGE_MAX_LENGTH} caracteres.`,
      );
      return;
    }

    if (!userMessage) {
      return;
    }

    setPending(true);
    setError(null);

    const optimisticUserMessage = {
      id: `${session.sessionId}-user-${session.userTurns + 1}`,
      role: "user" as const,
      content: userMessage,
      createdAt: new Date().toISOString(),
    };

    const previousSession = session;
    const optimisticSession: DemoSessionRecord = persistSession({
      ...session,
      transcript: [...session.transcript, optimisticUserMessage],
      updatedAt: optimisticUserMessage.createdAt,
      userTurns: session.userTurns + 1,
    });

    setSession(optimisticSession);
    setDraft("");

    try {
      const response = await fetch("/api/chat/turn", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          sessionId: session.sessionId,
          scenario: session.scenarioSnapshot,
          transcript: session.transcript,
          liveEvaluations: session.liveEvaluations,
          userTurns: session.userTurns,
          status: session.status,
          userMessage,
        }),
      });

      const payload = await readApiResponse(
        response,
        isTurnPayload,
        "La simulation n'a pas pu repondre.",
      );

      const nextStatus: ConversationStatus = payload.conversationStatus.status;
      const nextSession: DemoSessionRecord = persistSession({
        ...optimisticSession,
        transcript: [...optimisticSession.transcript, payload.assistantMessage],
        liveEvaluations: [
          ...optimisticSession.liveEvaluations,
          payload.liveEvaluation,
        ],
        status: nextStatus,
        updatedAt: payload.assistantMessage.createdAt,
      });

      setSession(nextSession);

      if (nextStatus !== "ongoing") {
        await finalizeCurrentSession(nextSession, nextStatus);
      }
    } catch (caughtError) {
      persistSession(previousSession);
      setSession(previousSession);
      setDraft(userMessage);
      setError(
        caughtError instanceof Error
          ? caughtError.message
          : "La simulation n'a pas pu repondre.",
      );
    } finally {
      setPending(false);
    }
  }

  async function handleManualEnd() {
    if (!session || pending || finalizing) {
      return;
    }

    const manualSession: DemoSessionRecord = persistSession({
      ...session,
      status: "manual_end",
      updatedAt: new Date().toISOString(),
    });

    setSession(manualSession);
    await finalizeCurrentSession(manualSession, "manual_end");
  }

  if (bootstrapping) {
    return (
      <main className="app-shell min-h-screen px-5 py-8 sm:px-8 lg:px-10">
        <div className="mx-auto flex min-h-[80vh] max-w-7xl items-center justify-center">
          <div className="glass-card rounded-[32px] px-8 py-10 text-center">
            <p className="text-sm font-semibold uppercase tracking-[0.22em] text-[var(--primary)]">
              Initialisation
            </p>
            <h1 className="mt-4 text-3xl font-extrabold text-[var(--ink)]">
              Preparation de votre simulation...
            </h1>
          </div>
        </div>
      </main>
    );
  }

  if (!session) {
    return (
      <main className="app-shell min-h-screen px-5 py-8 sm:px-8 lg:px-10">
        <div className="mx-auto flex min-h-[80vh] max-w-3xl items-center justify-center">
          <div className="glass-card rounded-[32px] px-8 py-10 text-center">
            <p className="text-sm font-semibold uppercase tracking-[0.22em] text-[var(--accent-red)]">
              Session indisponible
            </p>
            <h1 className="mt-4 text-3xl font-extrabold text-[var(--ink)]">
              La simulation n&apos;a pas pu etre chargee.
            </h1>
            <p className="mt-4 text-base leading-8 text-[var(--foreground)]">
              {error ??
                "Rechargez la page ou revenez a l&apos;accueil pour relancer un cas pratique."}
            </p>
            <Link
              href="/"
              className="mt-8 inline-flex rounded-full bg-[var(--primary)] px-6 py-3 text-sm font-semibold text-white transition-colors hover:bg-[var(--primary-strong)]"
            >
              Retour a l&apos;accueil
            </Link>
          </div>
        </div>
      </main>
    );
  }

  return (
    <MandatoryOnboardingGuard scope="app">
      <main className="app-shell min-h-screen px-5 py-8 sm:px-8 lg:px-10">
        <div className="relative z-10 mx-auto flex max-w-7xl flex-col gap-6">
          <header className="glass-card fade-in-up rounded-[32px] px-6 py-6 lg:px-8">
          <div className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
            <div className="flex items-center gap-4">
              <Link
                href="/"
                aria-label="Retour"
                className="inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-full border border-[var(--line)] text-[var(--foreground)] transition-colors hover:border-[var(--primary)] hover:text-[var(--primary)]"
              >
                <svg
                  aria-hidden="true"
                  viewBox="0 0 20 20"
                  className="h-5 w-5"
                  fill="none"
                  xmlns="http://www.w3.org/2000/svg"
                >
                  <path
                    d="M12.5 4.5L7 10L12.5 15.5"
                    stroke="currentColor"
                    strokeWidth="1.8"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                  />
                </svg>
              </Link>

              <h1 className="text-4xl font-extrabold tracking-[-0.04em] text-[var(--ink)]">
                {scenario.title}
              </h1>
            </div>

            <div className="flex flex-wrap gap-3">
              <span className="rounded-full bg-[rgba(23,117,186,0.10)] px-4 py-2 text-sm font-semibold text-[var(--primary)]">
                {scenario.difficulty}
              </span>
              <span className="rounded-full bg-[var(--surface-muted)] px-4 py-2 text-sm font-semibold text-[var(--foreground)]">
                {formatScenarioDurationLabel(scenario.maxTurns)}
              </span>
              <span className="rounded-full bg-[rgba(159,25,24,0.08)] px-4 py-2 text-sm font-semibold text-[var(--accent-red)]">
                {formatStatusLabel(session.status)}
              </span>
            </div>
          </div>
          </header>

          <div className="grid gap-6 xl:grid-cols-[minmax(0,1.28fr)_minmax(360px,0.72fr)]">
            <section className="glass-card fade-in-up flex min-h-[72vh] flex-col rounded-[32px]">
            <div className="border-b border-[var(--line)] px-6 py-5 lg:px-8">
              <div className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
                <div>
                  <p className="text-sm font-semibold uppercase tracking-[0.18em] text-[var(--accent-red)]">
                    Collaborateur incarne
                  </p>
                  <h2 className="mt-2 text-2xl font-bold text-[var(--ink)]">
                    {scenario.employeeProfile.name}, {scenario.employeeProfile.role}
                  </h2>
                  <p className="mt-2 text-sm leading-7 text-[var(--foreground)]">
                    Humeur initiale : {scenario.employeeProfile.currentMood}. Equipe :{" "}
                    {scenario.employeeProfile.team}.
                  </p>
                </div>
                <button
                  type="button"
                  onClick={handleManualEnd}
                  disabled={pending || finalizing}
                  className="inline-flex items-center justify-center rounded-full border border-[var(--line)] px-5 py-3 text-sm font-semibold text-[var(--foreground)] transition-colors hover:border-[var(--accent-red)] hover:text-[var(--accent-red)] disabled:cursor-not-allowed disabled:opacity-60"
                >
                  Terminer et generer le bilan
                </button>
              </div>
            </div>

            <div className="flex-1 overflow-y-auto px-6 py-6 lg:px-8">
              <div className="space-y-5">
                {session.transcript.map((message, index) => {
                  const isAssistant = message.role === "assistant";

                  return (
                    <article
                      key={message.id}
                      className={`fade-in-up flex ${
                        isAssistant ? "justify-start" : "justify-end"
                      }`}
                      style={{ animationDelay: `${index * 20}ms` }}
                    >
                      <div
                        className={`max-w-[90%] rounded-[28px] px-5 py-4 shadow-[0_10px_30px_rgba(35,52,61,0.05)] sm:max-w-[78%] ${
                          isAssistant
                            ? "border border-[var(--line)] bg-white text-[var(--ink)]"
                            : "bg-[var(--primary)] text-white"
                        }`}
                      >
                        <div className="flex items-center gap-2 text-xs font-semibold uppercase tracking-[0.2em] opacity-75">
                          <span>
                            {isAssistant
                              ? scenario.employeeProfile.name
                              : "Manager en entrainement"}
                          </span>
                          <span>&bull;</span>
                          <span>
                            {new Date(message.createdAt).toLocaleTimeString("fr-FR", {
                              hour: "2-digit",
                              minute: "2-digit",
                            })}
                          </span>
                        </div>
                        <p className="mt-3 whitespace-pre-wrap text-sm leading-7">
                          {message.content}
                        </p>
                      </div>
                    </article>
                  );
                })}

                {pending ? (
                  <div className="flex justify-start">
                    <div className="rounded-[28px] border border-[var(--line)] bg-white px-5 py-4 shadow-[0_10px_30px_rgba(35,52,61,0.05)]">
                      <div className="flex items-center gap-2 text-xs font-semibold uppercase tracking-[0.2em] text-[var(--foreground)]">
                        <span>{scenario.employeeProfile.name}</span>
                        <span>&bull;</span>
                        <span>en train de repondre</span>
                      </div>
                      <div className="mt-4 flex items-center gap-2 text-[var(--primary)]">
                        <span className="pulse-dot h-2.5 w-2.5 rounded-full bg-current [animation-delay:0ms]" />
                        <span className="pulse-dot h-2.5 w-2.5 rounded-full bg-current [animation-delay:150ms]" />
                        <span className="pulse-dot h-2.5 w-2.5 rounded-full bg-current [animation-delay:300ms]" />
                      </div>
                    </div>
                  </div>
                ) : null}

                <div ref={messagesEndRef} />
              </div>
            </div>

            <div className="border-t border-[var(--line)] px-6 py-5 lg:px-8">
              {error ? (
                <div className="mb-4 rounded-[24px] border border-[rgba(159,25,24,0.16)] bg-[rgba(159,25,24,0.06)] px-4 py-3 text-sm leading-7 text-[var(--accent-red)]">
                  {error}
                </div>
              ) : null}

              {session.finalAssessment ? (
                <div className="flex flex-col gap-3 rounded-[24px] border border-[rgba(47,138,99,0.16)] bg-[rgba(47,138,99,0.07)] px-4 py-4 sm:flex-row sm:items-center sm:justify-between">
                  <p className="text-sm font-semibold text-[var(--success)]">
                    Le bilan final est pret.
                  </p>
                  <Link
                    href={`/report/${session.sessionId}`}
                    className="inline-flex rounded-full bg-[var(--success)] px-5 py-3 text-sm font-semibold text-white"
                  >
                    Ouvrir le bilan
                  </Link>
                </div>
              ) : session.status !== "ongoing" ? (
                <div className="flex flex-col gap-3 rounded-[24px] border border-[var(--line)] bg-[var(--surface-soft)] px-4 py-4 sm:flex-row sm:items-center sm:justify-between">
                  <p className="text-sm font-semibold text-[var(--foreground)]">
                    La conversation est terminee. Generez ou regenerez le bilan
                    final pour cloturer la session.
                  </p>
                  <button
                    type="button"
                    onClick={() =>
                      finalizeCurrentSession(
                        session,
                        session.status as ConversationOutcome,
                      )
                    }
                    disabled={finalizing || pending}
                    className="inline-flex rounded-full bg-[var(--primary)] px-5 py-3 text-sm font-semibold text-white transition-colors hover:bg-[var(--primary-strong)] disabled:cursor-not-allowed disabled:opacity-60"
                  >
                    {finalizing ? "Generation..." : "Generer le bilan"}
                  </button>
                </div>
              ) : (
                <form onSubmit={handleSend} className="flex flex-col gap-4">
                  <textarea
                    value={draft}
                    onChange={(event) => setDraft(event.target.value)}
                    disabled={pending || finalizing || session.status !== "ongoing"}
                    maxLength={TRAINING_MESSAGE_MAX_LENGTH}
                    rows={4}
                    aria-describedby="training-message-meta"
                    placeholder="Saisissez votre reponse manageriale en francais..."
                    className="min-h-32 rounded-[28px] border border-[var(--line)] bg-white px-5 py-4 text-sm leading-7 text-[var(--ink)] outline-none transition-colors placeholder:text-[var(--foreground)]/70 focus:border-[var(--primary)] disabled:cursor-not-allowed disabled:opacity-60"
                  />
                  <div
                    id="training-message-meta"
                    className="flex flex-col gap-2 text-xs sm:flex-row sm:items-center sm:justify-between"
                  >
                    <p
                      className={
                        hasReachedMessageLimit
                          ? "font-semibold text-[var(--accent-red)]"
                          : "text-[var(--foreground)]"
                      }
                    >
                      {hasReachedMessageLimit
                        ? "Limite atteinte."
                        : "1200 caracteres maximum par message."}
                    </p>
                    <p
                      className={`font-semibold ${
                        hasReachedMessageLimit
                          ? "text-[var(--accent-red)]"
                          : isNearMessageLimit
                            ? "text-[var(--accent-gold)]"
                            : "text-[var(--foreground)]"
                      }`}
                    >
                      {draftLength}/{TRAINING_MESSAGE_MAX_LENGTH}
                    </p>
                  </div>
                  <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
                    <p className="text-sm text-[var(--foreground)]">
                      {session.userTurns} / {scenario.maxTurns} tours utilises
                    </p>
                    <button
                      type="submit"
                      disabled={
                        pending ||
                        finalizing ||
                        !draft.trim() ||
                        trimmedDraftLength > TRAINING_MESSAGE_MAX_LENGTH
                      }
                      className="inline-flex items-center justify-center rounded-full bg-[var(--primary)] px-6 py-3 text-sm font-semibold text-white transition-colors hover:bg-[var(--primary-strong)] disabled:cursor-not-allowed disabled:opacity-60"
                    >
                      Envoyer la reponse
                    </button>
                  </div>
                </form>
              )}
            </div>
            </section>

            <aside className="glass-card fade-in-up rounded-[32px] p-6 xl:sticky xl:top-6 xl:max-h-[calc(100vh-3rem)] xl:overflow-y-auto">
            <p className="text-sm font-semibold uppercase tracking-[0.2em] text-[var(--accent-gold)]">
              Analyseur de posture
            </p>
            <h2 className="mt-3 text-3xl font-extrabold tracking-[-0.04em] text-[var(--ink)]">
              Feedback qualitatif en direct
            </h2>
            <p className="mt-4 text-sm leading-7 text-[var(--foreground)]">
              Objectif du manager : {scenario.managerGoal}
            </p>

            <div className="mt-6 overflow-hidden rounded-[24px] border border-[var(--line)] bg-white">
              {latestEvaluation.metrics.map((metric) => (
                <div
                  key={metric.id}
                  className="border-b border-[var(--line)] px-4 py-4 last:border-b-0"
                >
                  <button
                    type="button"
                    onClick={() =>
                      setExpandedMetricId((current) =>
                        current === metric.id ? null : metric.id,
                      )
                    }
                    className="flex w-full items-center justify-between gap-3 text-left"
                  >
                    <div className="min-w-0 text-sm font-semibold text-[var(--ink)]">
                      <span>{metricMeta[metric.id].label}</span>
                      {hasStartedDiscussion ? (
                        <>
                          <span className="mx-2 text-[var(--foreground)]">-</span>
                          <span className="text-[var(--foreground)]">
                            {scoreToLevel(metric.score)}
                          </span>
                          <span className="mx-2 text-[var(--foreground)]">-</span>
                          <span>{metric.score}/100</span>
                        </>
                      ) : (
                        <>
                          <span className="mx-2 text-[var(--foreground)]">-</span>
                          <span className="text-[var(--foreground)]">
                            Demarrez la discussion
                          </span>
                        </>
                      )}
                    </div>
                    <svg
                      aria-hidden="true"
                      viewBox="0 0 20 20"
                      className={`h-4 w-4 shrink-0 text-[var(--foreground)] transition-transform ${
                        expandedMetricId === metric.id ? "rotate-90" : ""
                      }`}
                      fill="none"
                      xmlns="http://www.w3.org/2000/svg"
                    >
                      <path
                        d="M7 4L13 10L7 16"
                        stroke="currentColor"
                        strokeWidth="1.8"
                        strokeLinecap="round"
                        strokeLinejoin="round"
                      />
                    </svg>
                  </button>
                  {hasStartedDiscussion ? (
                    <div className="mt-3 h-2.5 rounded-full bg-[var(--surface-muted)]">
                      <div
                        className="metric-bar h-full rounded-full"
                        style={{ width: `${metric.score}%` }}
                      />
                    </div>
                  ) : null}
                  {expandedMetricId === metric.id ? (
                    <p className="mt-3 text-sm leading-7 text-[var(--foreground)]">
                      {metric.rationale}
                    </p>
                  ) : null}
                </div>
              ))}
            </div>

            <div className="mt-6 rounded-[24px] border border-[var(--line)] bg-[var(--surface-soft)] p-5">
              <p className="text-xs font-semibold uppercase tracking-[0.22em] text-[var(--accent-red)]">
                Conseil de cadrage
              </p>
              <p className="mt-3 text-sm leading-7 text-[var(--foreground)]">
                {latestEvaluation.coachingNote}
              </p>
            </div>

            <div className="mt-6 grid gap-4 md:grid-cols-2 xl:grid-cols-1">
              <div className="rounded-[24px] border border-[var(--line)] bg-[var(--surface-soft)] p-5">
                <p className="text-xs font-semibold uppercase tracking-[0.22em] text-[var(--primary)]">
                  Signal detecte
                </p>
                <p className="mt-3 text-sm leading-7 text-[var(--foreground)]">
                  {latestEvaluation.learnerSignal}
                </p>
              </div>

              <div className="rounded-[24px] border border-[var(--line)] bg-[var(--surface-soft)] p-5">
                <p className="text-xs font-semibold uppercase tracking-[0.22em] text-[var(--accent-red)]">
                  Points de vigilance
                </p>
                {latestEvaluation.riskFlags.length > 0 ? (
                  <ul className="mt-3 space-y-2 text-sm leading-7 text-[var(--foreground)]">
                    {latestEvaluation.riskFlags.map((flag) => (
                      <li key={flag}>&bull; {flag}</li>
                    ))}
                  </ul>
                ) : (
                  <p className="mt-3 text-sm leading-7 text-[var(--foreground)]">
                    Aucun point de risque critique pour l&apos;instant.
                  </p>
                )}
              </div>
            </div>

            <div className="mt-6 rounded-[24px] border border-[var(--line)] bg-white p-5">
              <p className="text-xs font-semibold uppercase tracking-[0.22em] text-[var(--accent-gold)]">
                Signaux de reussite
              </p>
              <ul className="mt-3 space-y-2 text-sm leading-7 text-[var(--foreground)]">
                {scenario.successSignals.map((signal) => (
                  <li key={signal}>&bull; {signal}</li>
                ))}
              </ul>
            </div>
            </aside>
          </div>
        </div>
      </main>
    </MandatoryOnboardingGuard>
  );
}
