import type { RemoteTrack } from 'livekit-client';
import { useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { type RemoteScreenShare, useCall } from '../context/CallContext';
import { MonitorShareIcon } from './icons';
import { ScreenShareAnnotations } from './ScreenShareAnnotations';

interface ScreenShareViewerProps {
  share: RemoteScreenShare;
  avatarUrl: string | null;
  displayName: string;
  /** Suppress the in-share fullscreen toggle button. Used inside cinema
   *  mode where (a) the window is already OS-fullscreen and (b) the
   *  toggle collides visually with FullscreenCall's strip-hidden button
   *  at the same top-right corner. */
  hideFullscreenToggle?: boolean;
}

// Click-to-watch gate, live <video> attach/detach, native fullscreen toggle.
// The watch-state lives in CallContext (not local useState) so it survives
// layout-mode changes (grid → focus → fullscreen) without resetting. Same
// reason the ScreenShareAudio mute follows this state — see attachTrack.
// Right-click handling happens one level up in TileRender — the wrapping
// div catches the event before it reaches the viewer's inner content.
export function ScreenShareViewer({
  share,
  avatarUrl,
  displayName,
  hideFullscreenToggle = false,
}: ScreenShareViewerProps) {
  const { t } = useTranslation(['app']);
  const videoRef = useRef<HTMLVideoElement | null>(null);
  const containerRef = useRef<HTMLDivElement | null>(null);
  const { watchingShareUserIds, watchShare } = useCall();
  const watching = watchingShareUserIds.has(share.participantId);
  const [isFullscreen, setIsFullscreen] = useState(false);
  const [annotateEnabled, setAnnotateEnabled] = useState(false);
  const letter = displayName.trim().charAt(0).toUpperCase() || '?';

  useEffect(() => {
    if (!watching) return;
    const el = videoRef.current;
    if (!el) return;
    const track: RemoteTrack = share.track;
    track.attach(el);
    return () => {
      track.detach(el);
    };
  }, [share.track, watching]);

  // Esc exits CSS fullscreen.
  useEffect(() => {
    if (!isFullscreen) return;
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') setIsFullscreen(false);
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [isFullscreen]);

  // CSS-only "app fullscreen" — Discord-style: overlay the whole window
  // including the left sidebar + chat list. Native Fullscreen API is
  // unreliable in Tauri's WKWebView and doesn't add useful chrome-hiding
  // beyond what `fixed inset-0 z-[60]` already gives us.
  const toggleFullscreen = () => {
    setIsFullscreen((v) => !v);
  };

  return (
    <div
      ref={containerRef}
      className={
        isFullscreen
          ? 'fixed inset-0 z-[60] flex h-screen w-screen flex-col overflow-hidden border-0 bg-black'
          : 'flex h-full w-full flex-col overflow-hidden rounded-xl border border-emerald-500/30 bg-black'
      }
    >
      <div className="flex shrink-0 items-center gap-2 border-b border-emerald-500/20 bg-emerald-500/15 px-3 py-1.5 text-xs text-emerald-700 dark:text-emerald-200">
        <MonitorShareIcon className="h-3.5 w-3.5 shrink-0" />
        <span className="flex-1 truncate">
          {t('app:call.is_sharing_screen', {
            name: displayName,
            defaultValue: displayName + ' teilt den Bildschirm',
          })}
        </span>
        {watching && !hideFullscreenToggle && (
          <button
            type="button"
            onClick={toggleFullscreen}
            aria-label={t('app:call.fullscreen', { defaultValue: 'Vollbild' })}
            title={t('app:call.fullscreen', { defaultValue: 'Vollbild' })}
            className="inline-flex h-6 w-6 cursor-pointer items-center justify-center rounded-md text-emerald-200 transition hover:bg-white/10 focus:outline-none focus-visible:ring-2 focus-visible:ring-emerald-400/40"
          >
            <FullscreenIcon className="h-3.5 w-3.5" />
          </button>
        )}
      </div>

      {watching ? (
        <div className="relative h-full w-full flex-1">
          <video
            ref={videoRef}
            autoPlay
            playsInline
            muted
            // Suppress the browser's built-in <video> context menu
            // ("Save Video As…", PiP, …) so the right-click event bubbles
            // to the wrapping tile div in InCallPanel — that's where the
            // app's volume / mute menu is wired up. Without this, the
            // native menu opens on top of ours in focus + fullscreen
            // modes (where the video covers the whole tile).
            onContextMenu={(e) => e.preventDefault()}
            onDoubleClick={toggleFullscreen}
            className="block h-full w-full cursor-zoom-in bg-black object-contain"
          />
          <ScreenShareAnnotations
            shareKey={share.participantId}
            enabled={annotateEnabled}
            onToggleEnabled={setAnnotateEnabled}
          />
        </div>
      ) : (
        <button
          type="button"
          onClick={() => watchShare(share.participantId)}
          aria-label={t('app:call.watch_screen', { defaultValue: 'Bildschirm anschauen' })}
          className="group relative block h-full w-full flex-1 cursor-pointer overflow-hidden bg-ink-900 focus:outline-none"
        >
          <BlurredTile avatarUrl={avatarUrl} letter={letter} />
          <div className="absolute inset-0 flex items-center justify-center bg-black/30 transition group-hover:bg-black/40">
            <div className="flex flex-col items-center gap-2">
              <span className="flex h-14 w-14 items-center justify-center rounded-full bg-emerald-500 text-white shadow-lg transition group-hover:scale-105">
                <PlayIcon className="ml-0.5 h-6 w-6" />
              </span>
              <span className="text-xs font-medium text-white/90">
                {t('app:call.watch_screen', { defaultValue: 'Bildschirm anschauen' })}
              </span>
            </div>
          </div>
        </button>
      )}
    </div>
  );
}

function BlurredTile({ avatarUrl, letter }: { avatarUrl: string | null; letter: string }) {
  if (avatarUrl) {
    return (
      <>
        <img
          src={avatarUrl}
          alt=""
          className="absolute inset-0 h-full w-full scale-110 object-cover blur-2xl"
        />
        <div className="absolute inset-0 bg-gradient-to-br from-accent/20 to-emerald-500/20" />
      </>
    );
  }
  return (
    <div className="absolute inset-0 flex items-center justify-center bg-gradient-to-br from-accent/40 via-fuchsia-500/20 to-emerald-500/30">
      <span
        aria-hidden="true"
        className="text-[120px] font-display font-bold text-white/20 blur-[2px]"
      >
        {letter}
      </span>
    </div>
  );
}

function PlayIcon(props: React.SVGProps<SVGSVGElement>) {
  return (
    <svg viewBox="0 0 24 24" fill="currentColor" {...props}>
      <path d="M8 5v14l11-7z" />
    </svg>
  );
}

function FullscreenIcon(props: React.SVGProps<SVGSVGElement>) {
  return (
    <svg
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth={2}
      strokeLinecap="round"
      strokeLinejoin="round"
      {...props}
    >
      <path d="M4 9V4h5M20 9V4h-5M4 15v5h5M20 15v5h-5" />
    </svg>
  );
}
