import { FolderPlus, Gear, Hash, PencilSimple, SignOut, Trash } from '@phosphor-icons/react';
import { useEffect, useRef } from 'react';
import styles from './ChannelListContextMenu.module.css';

interface ChannelListContextMenuProps {
	x: number;
	y: number;
	/** Set if right-clicking a category header */
	categoryId?: string;
	/** Set if right-clicking a channel (text or voice). Takes priority over categoryId. */
	channelId?: string;
	/** Label shown next to the Rename/Delete buttons, e.g. 'Channel' or 'Voice Channel' */
	channelTypeLabel?: string;
	onCreateChannel: () => void;
	onCreateCategory: () => void;
	onRenameCategory?: () => void;
	onCategorySettings?: () => void;
	onDeleteCategory?: () => void;
	onRenameChannel?: () => void;
	onDeleteChannel?: () => void;
	/**
	 * Shown when the user can't delete a channel (either because they lack
	 * the power level or because the channel is already an orphan in the
	 * local store). Leaves the room locally and removes the ChannelStore
	 * entry so the user can always nuke a phantom from their sidebar.
	 */
	onLeaveChannel?: () => void;
	onClose: () => void;
}

export function ChannelListContextMenu({
	x,
	y,
	categoryId,
	channelId,
	channelTypeLabel = 'Channel',
	onCreateChannel,
	onCreateCategory,
	onRenameCategory,
	onCategorySettings,
	onDeleteCategory,
	onRenameChannel,
	onDeleteChannel,
	onLeaveChannel,
	onClose,
}: ChannelListContextMenuProps) {
	const ref = useRef<HTMLDivElement>(null);

	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]);

	// Clamp position to viewport
	const style: React.CSSProperties = {
		top: Math.min(y, window.innerHeight - 120),
		left: Math.min(x, window.innerWidth - 200),
	};

	return (
		<div className={styles.overlay}>
			<div className={styles.menu} ref={ref} style={style}>
				{channelId ? (
					<>
						{onRenameChannel && (
							<button className={styles.menuItem} onClick={onRenameChannel}>
								<PencilSimple size={18} />
								<span>Rename {channelTypeLabel}</span>
							</button>
						)}
						{onDeleteChannel && (
							<button className={`${styles.menuItem} ${styles.menuItemDanger}`} onClick={onDeleteChannel}>
								<Trash size={18} />
								<span>Delete {channelTypeLabel}</span>
							</button>
						)}
						{/* Fallback when the user can't delete — always lets them
						    remove the channel from their own sidebar. */}
						{!onDeleteChannel && onLeaveChannel && (
							<button className={`${styles.menuItem} ${styles.menuItemDanger}`} onClick={onLeaveChannel}>
								<SignOut size={18} />
								<span>Leave {channelTypeLabel}</span>
							</button>
						)}
					</>
				) : categoryId ? (
					<>
						{onRenameCategory && (
							<button className={styles.menuItem} onClick={onRenameCategory}>
								<PencilSimple size={18} />
								<span>Rename Category</span>
							</button>
						)}
						{onCategorySettings && (
							<button className={styles.menuItem} onClick={onCategorySettings}>
								<Gear size={18} />
								<span>Category Settings</span>
							</button>
						)}
						{onDeleteCategory && (
							<button className={`${styles.menuItem} ${styles.menuItemDanger}`} onClick={onDeleteCategory}>
								<Trash size={18} />
								<span>Delete Category</span>
							</button>
						)}
					</>
				) : (
					<>
						<button className={styles.menuItem} onClick={onCreateChannel}>
							<Hash size={18} weight="bold" />
							<span>Create Channel</span>
						</button>
						<button className={styles.menuItem} onClick={onCreateCategory}>
							<FolderPlus size={18} />
							<span>Create Category</span>
						</button>
					</>
				)}
			</div>
		</div>
	);
}
