"use client";

import { useTranslation } from "@enode/core/translations/hooks";
import { Button } from "@enode/ui/button";
import { CloseXIcon, SpinnerIcon } from "@enode/ui/icons";
import { Sheet } from "@enode/ui/sheet";
import type { SessionRpeState } from "./payload";

// The confirmation after a session RPE, drawn over the closed questionnaire.
//
// It exists because the interesting part of a rating is not the rating: the
// server works out which workout it belongs to and multiplies by that workout's
// recorded volume to produce a training load. That is the number worth showing,
// and it only exists once the write has come back.
//
// Which is also why there is a pending state. The service reports `submitted`
// the moment the athlete taps, and `saved` only after the round trip — a real
// window in which the rating is logged and the outcome is genuinely unknown.

/**
 * The outcome in one line, or two when there is a load to lead with.
 *
 * Every branch here is a sentence that must not overclaim. A rating that
 * matched no workout, or matched one with no recorded sets, produces no
 * training load at all — never a load of zero.
 */
function Outcome({ state }: { state: SessionRpeState }) {
  const { t } = useTranslation();

  if (state.status === "pending") {
    return (
      <div className="flex items-center gap-2">
        <SpinnerIcon className="size-4 animate-spin text-foreground-muted" />
        <span className="body-small text-foreground-muted">{t("Saving…")}</span>
      </div>
    );
  }

  if (state.status === "failed") {
    return (
      <span className="body-small text-foreground-muted">
        {state.queued
          ? t("Not saved yet — kept on this device and sent when you're back online.")
          : t("This couldn't be saved. Your rating wasn't recorded.")}
      </span>
    );
  }

  const { sessionCount, trainingLoad } = state.result;

  // Stored against the athlete, but attached to nothing: no workout recorded in
  // the last day, or the one there was had already been rated.
  if (sessionCount === 0) {
    return (
      <span className="body-small text-foreground-muted">
        {t(
          "Saved. It wasn't matched to a workout, so there's no training load for it — either nothing was recorded in the last day, or that session was already rated.",
        )}
      </span>
    );
  }

  // A workout, but nothing to multiply by.
  if (trainingLoad === null) {
    return (
      <span className="body-small text-foreground-muted">
        {t(
          "Saved. No training load though — that session has no recorded sets or reps to weigh it against.",
        )}
      </span>
    );
  }

  return (
    <div className="flex flex-col gap-1">
      <span className="stat-large text-foreground-default">
        {t("Training load {load}", { load: Math.round(trainingLoad) })}
      </span>
      <span className="body-small text-foreground-more-muted">
        {t(
          "{count, plural, one {Across # workout} other {Across # workouts}} — this feeds your weekly load, monotony and strain.",
          { count: sessionCount },
        )}
      </span>
    </div>
  );
}

export function SessionRpeResultDrawer({
  state,
  onClose,
}: {
  /** Where the rating has got to, or null when nothing has been logged yet. */
  state: SessionRpeState | null;
  onClose: () => void;
}) {
  const { t } = useTranslation();

  return (
    <Sheet
      open={state !== null}
      onClose={onClose}
      slideFrom="bottom"
      ariaLabel={t("Session RPE result")}
      backdrop
      // Same status-bar inset as the questionnaire sheet it follows — this one
      // opens straight after it, so a header at a different height would read
      // as the screen jumping.
      className="flex flex-col bg-background pt-[env(safe-area-inset-top)]"
    >
      <header className="flex shrink-0 items-start justify-between gap-3 px-6 pt-6 pb-3 ios:px-4">
        <div className="min-w-0 space-y-1">
          <h1 className="heading-large">{t("Session logged")}</h1>
        </div>
        <button
          type="button"
          onClick={onClose}
          aria-label={t("Close")}
          className="flex size-10 shrink-0 items-center justify-center rounded-full bg-surface-base text-foreground-default shadow ring-1 ring-surface-stroke hover:bg-surface-base-muted"
        >
          <CloseXIcon className="size-5" />
        </button>
      </header>

      <div className="scrollbar-none min-h-0 flex-1 overflow-y-auto px-6 pb-8 ios:px-4">
        {state && (
          <div className="mx-auto flex w-full max-w-3xl flex-col gap-5">
            <p className="body-normal text-foreground-default">
              {t("Rated {rpe} out of 10", { rpe: state.payload.rpe })}
            </p>

            <Outcome state={state} />

            <Button variant="primary" size="rounded" onClick={onClose}>
              {t("Done")}
            </Button>
          </div>
        )}
      </div>
    </Sheet>
  );
}
