/**
 * The player.
 *
 * Two kinds of source, one frame. A Cap resource is a third-party document and
 * has to be an iframe with a sandbox; a PIG-hosted resource is bytes from this
 * origin and has to be a native `<video>`, because framing our own origin
 * would hand a media file a document context it has no business having. The
 * branch is on the resolved `kind`, never on the url — see `model.ts`.
 *
 * Nothing here builds a source. Every src arrives from the API already
 * resolved through the host allowlist in `@pig/core`; a resource the server
 * could not resolve is not in the response at all. Concatenating a URL in this
 * file would reintroduce exactly the hole the allowlist closes.
 *
 * The media box is a fixed `aspect-video` with an absolutely positioned child,
 * so the dialog is the same height before and after the embed loads. Sizing it
 * from the loaded content instead is what makes a player jump under the
 * pointer a beat after it opens.
 */
import { useEffect, useState } from 'react';
import { ExternalLink } from 'lucide-react';
import { formatLearnDuration, LEARN_TRACK_LABELS } from '@pig/core';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Badge } from '@/components/ui';
import { learnPlayback, watchHost, type LearnResourceView } from './model';

export function LearnPlayerDialog({
  resource,
  onClose,
}: {
  resource: LearnResourceView | null;
  onClose: () => void;
}) {
  // Reset per resource, or a failure on one video would persist as the error
  // state of the next one opened.
  const [failed, setFailed] = useState(false);
  useEffect(() => setFailed(false), [resource?.id]);

  const playback = resource ? learnPlayback(resource) : null;
  const duration = formatLearnDuration(resource?.durationSeconds);
  const host = watchHost(resource?.watchUrl);

  return (
    <Dialog open={resource !== null} onOpenChange={(next) => !next && onClose()}>
      {/* Esc and the overlay both close it — Radix's behaviour, kept. */}
      <DialogContent className="max-h-[92dvh] w-[calc(100vw-1.5rem)] max-w-4xl gap-0 overflow-y-auto p-0">
        {resource ? (
          <>
            <DialogHeader className="min-w-0 gap-1 p-4 pr-14 text-left sm:p-5 sm:pr-16">
              <DialogTitle className="min-w-0 break-words text-base leading-snug sm:text-lg">
                {resource.title}
              </DialogTitle>
              <DialogDescription className="min-w-0 break-words">
                {resource.summary ?? `${LEARN_TRACK_LABELS[resource.track]} track.`}
              </DialogDescription>
            </DialogHeader>

            <div className="relative aspect-video w-full min-w-0 border-y border-border bg-surface-2">
              {playback?.kind === 'video' ? (
                <video
                  key={resource.id}
                  src={playback.src}
                  poster={playback.poster}
                  controls
                  playsInline
                  preload="metadata"
                  className="absolute inset-0 size-full"
                  /*
                   * A resolved source that will not load is an ORDINARY state
                   * here, not an edge case: media filenames are content-
                   * addressed, so re-rendering a video leaves the old row
                   * pointing at a file that no longer exists, and the seed
                   * deliberately reports that rather than resolving it. Without
                   * this the viewer gets a black rectangle with a scrubber that
                   * does nothing and no explanation.
                   */
                  onError={() => setFailed(true)}
                />
              ) : null}
              {playback?.kind === 'iframe' ? (
                /*
                 * The sandbox keeps the frame from navigating the top window or
                 * opening downloads; `allow-same-origin` is safe and necessary
                 * here because the frame is cross-origin, so "same origin"
                 * means the video host's own, not PIG's.
                 */
                <iframe
                  key={resource.id}
                  src={playback.src}
                  title={resource.title}
                  className="absolute inset-0 size-full border-0"
                  allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
                  allowFullScreen
                  referrerPolicy="strict-origin-when-cross-origin"
                  sandbox="allow-scripts allow-same-origin allow-presentation"
                />
              ) : null}
              {!playback || failed ? (
                <p className="absolute inset-0 flex items-center justify-center bg-surface-2 p-6 text-center text-sm text-muted">
                  {failed
                    ? 'This video could not be loaded. The recording may have been replaced — ask an admin to refresh it.'
                    : 'This video has no playable source.'}
                </p>
              ) : null}
            </div>

            <div className="flex min-w-0 flex-wrap items-center gap-x-3 gap-y-2 p-4 sm:p-5">
              <Badge tone="neutral">{LEARN_TRACK_LABELS[resource.track]}</Badge>
              {duration ? <Badge tone="neutral" className="nums">{duration}</Badge> : null}
              {playback?.kind === 'iframe' && resource.watchUrl ? (
                <a
                  href={resource.watchUrl}
                  target="_blank"
                  rel="noreferrer noopener"
                  className="tap ml-auto inline-flex min-w-0 items-center gap-1.5 text-sm font-medium text-accent-fg underline-offset-4 hover:underline"
                >
                  <ExternalLink className="size-4 shrink-0" aria-hidden />
                  <span className="min-w-0 break-words">Open on {host ?? 'the video host'}</span>
                </a>
              ) : null}
            </div>
          </>
        ) : null}
      </DialogContent>
    </Dialog>
  );
}
