import React, { useMemo } from 'react';
import { Text } from 'folds';
import { isNativePlatform } from '../../utils/capacitor';

// Dancing-mascot pull-to-refresh asset — the pink "evil mascot" working
// out (dumbbells + radar rings), cut to a seamless 2s loop, background
// keyed to alpha, VP9. SEPARATE from the auth `mascot.*` (the purple
// idle mascot), which is unchanged.
import mascotPoster from '../../../../public/res/img/mascot-dance.png';
import mascotWebm from '../../../../public/res/img/mascot-dance.webm';
import * as css from './StreamHeader.css';

type RefreshMascotProps = {
  // Caption under the mascot («Обновляем…»). Passed by StreamHeader so the
  // copy stays in the i18n layer rather than baked in here.
  caption: string;
  // True while the curtain is revealing — or resting at — the refresh card
  // (refresh snap, or a live down-drag from closed). Only then do we mount
  // the looping <video>; otherwise (curtain closed, card z-occluded) we
  // render the still poster so the decoder isn't running behind the
  // curtain 24/7. The card is z-covered + aria-hidden at rest, and the
  // poster is the clip's first frame, so the poster↔video swap is
  // invisible and the dance starts seamlessly on reveal.
  revealing: boolean;
  // Forwarded to the dance <video> so StreamHeader can read the loop position
  // and defer the pull-to-refresh auto-close to a loop boundary — the curtain
  // never rises mid-dance. Null while the still poster (reduced-motion /
  // not-yet-revealed) is shown instead of the video.
  videoRef?: React.Ref<HTMLVideoElement>;
  // Called when the user taps the mascot — StreamHeader spawns a one-shot
  // "echo" pulse ring on top of the ambient radar. A clean tap fires this;
  // a drag instead bubbles to the curtain body gesture (it moves past the
  // dead-zone → `preventDefault` → the browser suppresses the click), so the
  // poke never fights the pull gesture.
  onPoke?: () => void;
};

// The card revealed below the tabs row by the curtain's `refresh` snap:
// a looping dancing mascot, painted in the header's `SurfaceVariant.
// Container` tone. The mascot dances during the pull-to-refresh; no
// caption — the animation is the whole affordance (Claude-mobile-app
// style).
//
// Two hosts: the in-stage header slot on NON-pager native surfaces, and
// the strip-hosted PagerRefreshSingleton in pager mode, where the card
// stays put while the panes slide and `onPoke` is omitted (the singleton
// is pointer-events-none; pokes arrive via the per-pane tap-catcher
// through `mobilePagerMascotApiAtom`).
//
// We render a plain `<video>` — NOT the auth `mascotSingleton`
// currentTime-preservation machinery, which solves a cold-boot remount
// problem this surface doesn't have; the two mascot surfaces stay
// decoupled by design.
//
// Native-only: the curtain pull-to-refresh gesture is native-only (web
// has no drag), so the card would never be revealed on web — skip
// mounting it there entirely.
//
// `prefers-reduced-motion`: fall back to the still poster so the reveal
// honours the OS motion-reduction setting. (Read once at mount; the rest
// of the app reads this query one-shot too, and this card is native-only
// + aria-hidden, so a mid-session OS toggle not re-evaluating here is
// acceptable.)
export function RefreshMascot({ caption, revealing, videoRef, onPoke }: RefreshMascotProps) {
  const native = isNativePlatform();

  const reducedMotion = useMemo(
    () =>
      typeof window !== 'undefined' &&
      !!window.matchMedia &&
      window.matchMedia('(prefers-reduced-motion: reduce)').matches,
    []
  );

  if (!native) return null;

  const showVideo = revealing && !reducedMotion;

  return (
    <div
      className={css.mascotCard}
      aria-hidden="true"
      // Tap-to-poke easter-egg: spawn an echo ring. The card is decorative +
      // aria-hidden (sighted-only delight), so no keyboard/role affordance
      // applies — drag-to-refresh stays the real interaction.
      // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
      onClick={onPoke}
    >
      {/* The radar-pulse rings live at the host level (StreamHeader's stage
          layer, or the strip-hosted singleton), not here — they break out of
          this «formal» card and ripple across the whole chrome. This card
          holds just the mascot + caption. */}
      {showVideo ? (
        <video
          ref={videoRef}
          className={css.mascotMedia}
          src={mascotWebm}
          poster={mascotPoster}
          autoPlay
          loop
          muted
          playsInline
        />
      ) : (
        <img className={css.mascotMedia} src={mascotPoster} alt="" />
      )}
      <Text className={css.mascotCaption} size="T200" priority="300">
        {caption}
      </Text>
    </div>
  );
}
