/**
 * The invitation, composed in three parts (tasks 6.1-6.3, design D7).
 *
 *   header  — the personal greeting, and nothing else
 *   body    — the card design, dominant
 *   footer  — one call to action
 *
 * Everything that used to sit between the greeting and the RSVP — countdown, date, venue,
 * directions, notes, host contact — now sits *below* the call to action. That is the whole
 * point of the re-composition: a guest opening this on a phone should see who it is for,
 * the artwork, and one thing to press. The supporting detail is still complete, still text,
 * still in the initial HTML (PRD §9.2) — just no longer competing with the card.
 *
 * Still a server component. Names, date, venue, map link and the host's phone number are in
 * the HTML before any JavaScript runs; the animated pieces are client components layered on
 * top that render nothing on the server.
 */
import { CardZoom } from "./CardZoom";
import { Countdown } from "./Countdown";
import { EnvelopeReveal } from "./EnvelopeReveal";
import { InvitationCard } from "./InvitationCard";
import { MusicToggle } from "./MusicToggle";
import {
  eventTitle,
  formatEventDate,
  formatEventTime,
  hostNameLine,
  type Dictionary,
} from "@/lib/i18n";
import type { CardView, CoupleView, EventView, GreetingView, Locale } from "@/lib/view-models";

export function InvitationShell({
  event,
  couple,
  locale,
  dict,
  greeting,
  guestName,
  card,
  children,
}: {
  event: EventView;
  couple: CoupleView;
  locale: Locale;
  dict: Dictionary;
  greeting: GreetingView;
  /** Absent on the tokenless route, where no guest is known. */
  guestName?: string | null;
  /** The published card design, when the event has one. */
  card: CardView | null;
  /** The call to action. Rendered in the footer, never in the flow beneath the artwork. */
  children: React.ReactNode;
}) {
  const title = eventTitle(locale, event);

  return (
    <main className="mx-auto flex min-h-dvh max-w-md flex-col px-5 py-8">
      {/* Both are client components that render nothing on the server, so the invitation
          below is complete in the initial HTML either way (PRD §9.2). */}
      <EnvelopeReveal
        id={event.slug}
        coupleName={couple.displayName}
        eventTitle={title}
        dict={dict}
      />
      <MusicToggle src={event.musicUrl} dict={dict} />

      {/* HEADER — greeting only. Transparent, centred, no card and no border: it sits on
          the page rather than in a box, so it reads as a note above the artwork instead of
          a second competing panel. Deliberately small type and generous but bounded spacing
          so it keeps a minor share of the first screen. */}
      <header className="shrink-0 pb-5 text-center">
        {guestName && (
          // `break-words` and no truncation: a long name wraps onto further lines and the
          // card moves down. Clipping someone's name on their own invitation is not an
          // acceptable way to protect a layout.
          <p className="text-base break-words hyphens-none">
            {dict.dear}{" "}
            <strong className="font-semibold">{guestName}</strong>,
          </p>
        )}
        <p className={`text-sm opacity-80 ${guestName ? "mt-1" : ""}`}>{greeting.message}</p>
      </header>

      {/* BODY — the card, dominant. `flex-1` lets it take the space the header and footer
          do not, which is what makes the proportion hold at every viewport height rather
          than at one nominal size. */}
      <section aria-label={title} className="flex min-h-0 flex-1 flex-col justify-center">
        {card ? (
          <CardZoom openLabel={dict.viewCard} closeLabel={dict.close}>
            <InvitationCard card={card} event={event} couple={couple} locale={locale} dict={dict} />
          </CardZoom>
        ) : (
          // No card, nothing to enlarge: the plain composition is already at full size.
          <InvitationCard card={null} event={event} couple={couple} locale={locale} dict={dict} />
        )}
      </section>

      {/* FOOTER — one call to action. Nothing else renders here. */}
      <footer className="shrink-0 pt-6">{children}</footer>

      {/* Below the fold: everything the guest may want after deciding to come. Present,
          readable, and never gated behind JavaScript — just not on the first screen. */}
      <div className="mt-10 flex flex-col gap-6 border-t border-current/10 pt-8">
        <section aria-label="Countdown">
          <Countdown startsAt={event.startsAt} dict={dict} />
        </section>

        <section className="flex flex-col gap-2">
          <p className="text-lg font-medium">{formatEventDate(event.startsAt, locale)}</p>
          <p className="text-base">{formatEventTime(event.startsAt, locale)}</p>
          <p className="mt-2 text-base font-medium">{event.venueName}</p>
          <p className="text-sm opacity-80">{event.venueAddress}</p>
          {event.dressCode && (
            <p className="mt-2 text-sm">
              <span className="opacity-70">{dict.dressCode}:</span> {event.dressCode}
            </p>
          )}
          {event.mapUrl && (
            <a
              href={event.mapUrl}
              target="_blank"
              rel="noreferrer noopener"
              className="mt-3 inline-flex min-h-11 items-center justify-center rounded-full border px-5 text-base"
            >
              {dict.getDirections}
            </a>
          )}
        </section>

        {event.notes && <p className="text-center text-sm opacity-80">{event.notes}</p>}

        {/* No "you're also invited to…" list. A guest record belongs to one event
            (design D11), so there is no other invitation this one can honestly link to. */}

        {/* HOST BLOCK — who is inviting this guest, last on the page, the way a printed
            card signs off (design D11). It replaces the wedding-wide phone that used to sit
            here unlabelled: that number was the same for every event, which is wrong when
            the Mehedi and the Walima are hosted by different families.

            Fixed for the event and carrying no guest data, so `/e/{slug}` renders it too. */}
        <section aria-label={dict.invitedBy} className="pb-6 text-center">
          {/* Subordinate to the names on purpose — the label says what follows is, the
              names are what the guest actually reads. */}
          <p className="text-xs tracking-wide uppercase opacity-60">{dict.invitedBy}</p>
          {/* `break-words` and no truncation, same rule as the guest's name in the header:
              two long names joined by the joining word must wrap, never be clipped. */}
          <p className="mt-1 text-base font-medium break-words hyphens-none">
            {hostNameLine(dict, event)}
          </p>
          <p className="mt-1 text-sm opacity-70">
            <a href={`tel:${event.hostPhone}`} className="underline">
              {event.hostPhone}
            </a>
          </p>
        </section>
      </div>
    </main>
  );
}
