import {
	At,
	MicrophoneSlash,
	PencilSimple,
	PhoneX,
	SpeakerSimpleHigh,
	SpeakerSimpleSlash,
	User as UserIcon,
} from '@phosphor-icons/react';
/**
 * VoiceParticipantContextMenu — right-click menu for users in the
 * voice channel sidebar. Includes the standard profile/message
 * actions plus voice-specific ones (volume, server mute, server
 * deafen, disconnect). Admin-only items are gated by the caller
 * passing the corresponding callback — missing callbacks hide the
 * row, same pattern MemberContextMenu uses.
 */
import { useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import baseStyles from '../layout/ChannelListContextMenu.module.css';
import styles from './VoiceParticipantContextMenu.module.css';

interface VoiceParticipantContextMenuProps {
	x: number;
	y: number;
	onViewProfile: () => void;
	onMessage: () => void;
	/** Optional — only shown when in the same call as the target. */
	onVolumeChange?: (level: number) => void;
	/** Current volume (0..2) for the slider. */
	currentVolume?: number;
	/** Optional — admin-only actions. */
	onChangeNickname?: () => void;
	onToggleServerMute?: () => void;
	onToggleServerDeafen?: () => void;
	onDisconnect?: () => void;
	/** Current moderation state for labels. */
	isServerMuted?: boolean;
	isServerDeafened?: boolean;
	onClose: () => void;
}

export function VoiceParticipantContextMenu({
	x,
	y,
	onViewProfile,
	onMessage,
	onVolumeChange,
	currentVolume = 1,
	onChangeNickname,
	onToggleServerMute,
	onToggleServerDeafen,
	onDisconnect,
	isServerMuted = false,
	isServerDeafened = false,
	onClose,
}: VoiceParticipantContextMenuProps) {
	const ref = useRef<HTMLDivElement>(null);
	// Local slider state so dragging doesn't clobber onClose's
	// click-outside detection. Applied to the store on change.
	const [volume, setVolume] = useState(Math.round((currentVolume ?? 1) * 100));

	useEffect(() => {
		const handleClick = (e: MouseEvent) => {
			if (ref.current && !ref.current.contains(e.target as Node)) {
				onClose();
			}
		};
		const handleEscape = (e: KeyboardEvent) => {
			if (e.key === 'Escape') onClose();
		};
		document.addEventListener('mousedown', handleClick);
		document.addEventListener('keydown', handleEscape);
		return () => {
			document.removeEventListener('mousedown', handleClick);
			document.removeEventListener('keydown', handleEscape);
		};
	}, [onClose]);

	const style: React.CSSProperties = {
		top: Math.min(y, window.innerHeight - 320),
		left: Math.min(x, window.innerWidth - 220),
	};

	const hasAdminSection = !!(onChangeNickname || onToggleServerMute || onToggleServerDeafen || onDisconnect);

	return createPortal(
		<div className={baseStyles.overlay}>
			<div className={baseStyles.menu} ref={ref} style={style}>
				<button type="button" className={baseStyles.menuItem} onClick={onViewProfile}>
					<UserIcon size={18} weight="fill" />
					<span>View Profile</span>
				</button>
				<button type="button" className={baseStyles.menuItem} onClick={onMessage}>
					<At size={18} weight="bold" />
					<span>Message</span>
				</button>

				{onVolumeChange && (
					<>
						<div className={baseStyles.separator} />
						<div className={styles.volumeRow}>
							<div className={styles.volumeLabel}>
								<SpeakerSimpleHigh size={16} weight="fill" />
								<span>User Volume</span>
								<span className={styles.volumeValue}>{volume}%</span>
							</div>
							<input
								type="range"
								min={0}
								max={200}
								step={1}
								value={volume}
								onChange={(e) => {
									const next = Number(e.target.value);
									setVolume(next);
									onVolumeChange(next / 100);
								}}
								className={styles.volumeSlider}
							/>
						</div>
					</>
				)}

				{hasAdminSection && <div className={baseStyles.separator} />}

				{onChangeNickname && (
					<button type="button" className={baseStyles.menuItem} onClick={onChangeNickname}>
						<PencilSimple size={18} weight="fill" />
						<span>Change Nickname</span>
					</button>
				)}

				{onToggleServerMute && (
					<button type="button" className={baseStyles.menuItem} onClick={onToggleServerMute}>
						<MicrophoneSlash size={18} weight="fill" />
						<span>{isServerMuted ? 'Unmute' : 'Server Mute'}</span>
					</button>
				)}

				{onToggleServerDeafen && (
					<button type="button" className={baseStyles.menuItem} onClick={onToggleServerDeafen}>
						<SpeakerSimpleSlash size={18} weight="fill" />
						<span>{isServerDeafened ? 'Undeafen' : 'Server Deafen'}</span>
					</button>
				)}

				{onDisconnect && (
					<button
						type="button"
						className={`${baseStyles.menuItem} ${baseStyles.menuItemDanger}`}
						onClick={onDisconnect}
					>
						<PhoneX size={18} weight="fill" />
						<span>Disconnect</span>
					</button>
				)}
			</div>
		</div>,
		document.body,
	);
}
