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

import {
  getParticipantVolume,
  setParticipantVolume,
  subscribeParticipantVolumes,
} from '../lib/participantVolumes';

interface Props {
  userId: string;
  displayName: string;
  x: number;
  y: number;
  onClose: () => void;
}

const MENU_W = 240;
const MENU_H = 96;

export function ParticipantVolumeMenu({
  userId,
  displayName,
  x,
  y,
  onClose,
}: Props) {
  const [volume, setVolume] = useState<number>(() => getParticipantVolume(userId));

  // Re-sync from store in case another menu instance changed the same user.
  useEffect(() => subscribeParticipantVolumes(() => {
    setVolume(getParticipantVolume(userId));
  }), [userId]);

  // Outside click + Esc to close.
  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-volume-menu]')) return;
      onClose();
    };
    window.addEventListener('keydown', onKey);
    window.addEventListener('mousedown', onDown);
    return () => {
      window.removeEventListener('keydown', onKey);
      window.removeEventListener('mousedown', onDown);
    };
  }, [onClose]);

  const left = Math.min(Math.max(8, x), window.innerWidth - MENU_W - 8);
  const top = Math.min(Math.max(8, y), window.innerHeight - MENU_H - 8);

  return createPortal(
    <div
      data-volume-menu
      role="dialog"
      aria-label={'Lautstärke ' + displayName}
      style={{ left, top, width: MENU_W }}
      className="fixed z-[80] rounded-xl border border-line bg-surface-2/95 p-3 shadow-xl backdrop-blur-md"
    >
      <div className="mb-2 flex items-center justify-between gap-2 text-xs">
        <span className="truncate font-semibold text-fg">{displayName}</span>
        <span
          className={
            'tabular-nums ' + (volume > 1 ? 'text-amber-500' : 'text-fg-muted')
          }
        >
          {Math.round(volume * 100)}%
        </span>
      </div>
      {/* Up to 200% via WebAudio gain. Values above 100% can clip on loud
          mics — the amber count-up hints at that without a verbose warning. */}
      <input
        type="range"
        min={0}
        max={2}
        step={0.01}
        value={volume}
        onChange={(e) => {
          const v = Number(e.target.value);
          setVolume(v);
          setParticipantVolume(userId, v);
        }}
        aria-label={'Lautstärke ' + displayName}
        className="w-full accent-accent"
      />
      <div className="mt-1 flex justify-between text-[10px] text-fg-muted">
        <span>0%</span>
        <span className="tabular-nums">100%</span>
        <span>200%</span>
      </div>
    </div>,
    document.body,
  );
}
