import { useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { useTranslation } from 'react-i18next';

import { useCall } from '../context/CallContext';
import {
  getScreenShareVolume,
  setScreenShareVolume,
  subscribeScreenShareVolumes,
} from '../lib/screenShareVolumes';
import { EyeOffIcon, HeadphonesIcon, HeadphonesOffIcon, MonitorShareIcon, PhoneOffIcon } from './icons';

interface Props {
  /** Participant whose screen share the user right-clicked. */
  userId: string;
  displayName: string;
  /** Whether the share has an audio track published. Controls whether the
   *  volume / mute rows render — without audio those would be no-ops. */
  hasAudio: boolean;
  x: number;
  y: number;
  onClose: () => void;
}

const MENU_W = 260;
// Heights bumped to fit the new "Tile ausblenden" row (38px each).
const MENU_H_WITH_AUDIO = 240;
const MENU_H_NO_AUDIO = 134;

// Context menu surfaced on right-click of a remote screen share. Mirrors
// Discord's stream menu: volume slider, audio mute toggle (independent of
// volume — matches HTMLMediaElement's `muted` field), and "stop watching"
// which both un-subscribes locally and dismisses the tile from the grid.
export function ScreenShareContextMenu({
  userId,
  displayName,
  hasAudio,
  x,
  y,
  onClose,
}: Props) {
  const { t } = useTranslation(['app']);
  const {
    dismissShare,
    stopWatchingShare,
    watchingShareUserIds,
    screenShareAudioMutedIds,
    setScreenShareAudioMuted,
  } = useCall();
  const watching = watchingShareUserIds.has(userId);
  const [volume, setVolume] = useState<number>(() => getScreenShareVolume(userId));

  useEffect(
    () =>
      subscribeScreenShareVolumes(() => {
        setVolume(getScreenShareVolume(userId));
      }),
    [userId],
  );

  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
    };
    const onDown = (e: MouseEvent) => {
      const target = e.target as HTMLElement | null;
      if (target?.closest('[data-share-menu]')) return;
      onClose();
    };
    window.addEventListener('keydown', onKey);
    window.addEventListener('mousedown', onDown);
    return () => {
      window.removeEventListener('keydown', onKey);
      window.removeEventListener('mousedown', onDown);
    };
  }, [onClose]);

  const muted = screenShareAudioMutedIds.has(userId);
  const height = hasAudio ? MENU_H_WITH_AUDIO : MENU_H_NO_AUDIO;
  const left = Math.min(Math.max(8, x), window.innerWidth - MENU_W - 8);
  const top = Math.min(Math.max(8, y), window.innerHeight - height - 8);

  return createPortal(
    <div
      data-share-menu
      role="menu"
      aria-label={t('app:call.share_menu_title', {
        defaultValue: 'Bildschirmfreigabe von {{name}}',
        name: displayName,
      })}
      style={{ left, top, width: MENU_W }}
      className="fixed z-[80] overflow-hidden rounded-xl border border-line bg-surface-2/95 text-sm shadow-xl backdrop-blur-md"
    >
      <header className="flex items-center gap-2 border-b border-line px-3 py-2 text-xs text-fg-muted">
        <MonitorShareIcon className="h-3.5 w-3.5 shrink-0 text-emerald-500" />
        <span className="truncate">
          {t('app:call.share_menu_owner', {
            defaultValue: 'Bildschirmfreigabe · {{name}}',
            name: displayName,
          })}
        </span>
      </header>

      {hasAudio && (
        <>
          <div className="flex flex-col gap-1.5 px-3 py-2.5">
            <div className="flex items-center justify-between text-xs">
              <span className="font-medium text-fg">
                {t('app:call.share_volume', { defaultValue: 'Lautstärke' })}
              </span>
              <span
                className={
                  'tabular-nums ' + (volume > 1 ? 'text-amber-500' : 'text-fg-muted')
                }
              >
                {Math.round(volume * 100)}%
              </span>
            </div>
            <input
              type="range"
              min={0}
              max={2}
              step={0.01}
              value={volume}
              onChange={(e) => {
                const v = Number(e.target.value);
                setVolume(v);
                setScreenShareVolume(userId, v);
              }}
              aria-label={t('app:call.share_volume', { defaultValue: 'Lautstärke' })}
              className="w-full accent-accent"
            />
            <div className="flex justify-between text-[10px] text-fg-muted">
              <span>0%</span>
              <span>100%</span>
              <span>200%</span>
            </div>
          </div>
          <button
            type="button"
            onClick={() => setScreenShareAudioMuted(userId, !muted)}
            className="flex w-full cursor-pointer items-center gap-2 border-t border-line px-3 py-2 text-left text-xs text-fg transition hover:bg-surface-3"
          >
            {muted ? (
              <HeadphonesOffIcon className="h-4 w-4 text-rose-500" />
            ) : (
              <HeadphonesIcon className="h-4 w-4 text-fg-muted" />
            )}
            <span className="flex-1">
              {muted
                ? t('app:call.share_unmute_audio', { defaultValue: 'Audio einschalten' })
                : t('app:call.share_mute_audio', { defaultValue: 'Audio stumm' })}
            </span>
          </button>
        </>
      )}

      {/* Discord-parity: "Stop watching" only ends the local subscription;
          the tile stays so the user can re-click to watch again. The full
          dismiss path (kill the tile until the sharer restarts) is the
          second row below. */}
      {watching && (
        <button
          type="button"
          onClick={() => {
            stopWatchingShare(userId);
            onClose();
          }}
          className="flex w-full cursor-pointer items-center gap-2 border-t border-line px-3 py-2 text-left text-xs text-fg transition hover:bg-surface-3"
        >
          <PhoneOffIcon className="h-4 w-4 text-fg-muted" />
          <span>
            {t('app:call.stop_watching', { defaultValue: 'Zuschauen beenden' })}
          </span>
        </button>
      )}
      <button
        type="button"
        onClick={() => {
          dismissShare(userId);
          onClose();
        }}
        className="flex w-full cursor-pointer items-center gap-2 border-t border-line px-3 py-2 text-left text-xs font-semibold text-rose-600 transition hover:bg-rose-500/10 dark:text-rose-300"
      >
        <EyeOffIcon className="h-4 w-4" />
        <span>
          {t('app:call.dismiss_tile', { defaultValue: 'Stream-Tile ausblenden' })}
        </span>
      </button>
    </div>,
    document.body,
  );
}
