/**
 * MobileMessageActionsSheet — long-press menu for messages on mobile.
 * Mirrors the action set in `MessageActionBar` (the desktop hover bar
 * + its More menu) but laid out as a bottom sheet drawer instead of a
 * floating popover, since hover-based UI doesn't work on touch.
 *
 * Layout matches Discord/Fluxer mobile:
 *   ┌────── drag handle ──────┐
 *   │  [👍] [👌] [🎉] [❤] [+]  │   ← quick reactions row
 *   ├──────────────────────────┤
 *   │  ☺  Add Reaction          │
 *   │  ↩  Reply                 │
 *   │  →  Forward               │
 *   │  ✎  Edit Message          │   (own messages only)
 *   │  📌 Pin Message           │
 *   │  ⧉  Copy Text             │
 *   │  🔍 Inspect Message       │
 *   │  🗑  Delete Message       │   (own messages or admins)
 *   └──────────────────────────┘
 *
 * Reuses `BottomSheet` from `@brycord/ui` (same component the emoji
 * picker and channel-details drawer use). Each action call closes
 * the sheet immediately so the user sees the result of their tap
 * without an extra dismiss step.
 */
import {
	Smiley,
	ArrowBendUpLeft,
	ArrowBendUpRight,
	PencilSimple,
	Trash,
	PushPin,
	Copy,
	MagnifyingGlass,
	Plus,
} from '@phosphor-icons/react';
import { BottomSheet } from '@discord-clone/ui';
import styles from './MobileMessageActionsSheet.module.css';

// Mirrors the QUICK_EMOJIS in MessageActionBar so users get the same
// shortcuts on mobile as on desktop. Adding a 4th gives the row
// better visual rhythm with the trailing "+" tile (5 cells total).
const QUICK_EMOJIS = [
	{ emoji: '👍', name: 'thumbsup' },
	{ emoji: '👌', name: 'ok_hand' },
	{ emoji: '🎉', name: 'tada' },
	{ emoji: '❤️', name: 'heart' },
];

function emojiToCodepoint(emoji: string): string {
	const codepoints: string[] = [];
	for (let i = 0; i < emoji.length; i++) {
		const code = emoji.codePointAt(i)!;
		if (code === 0xfe0f) continue;
		codepoints.push(code.toString(16));
		if (code > 0xffff) i++;
	}
	return codepoints.join('-');
}

interface MobileMessageActionsSheetProps {
	isOpen: boolean;
	onClose: () => void;
	isOwnMessage: boolean;
	canDelete: boolean;
	hasContent: boolean;
	/** Quick reaction handler — receives the unicode emoji string. */
	onQuickReact: (emoji: string) => void;
	/** Opens the full reaction picker. */
	onAddReaction: () => void;
	onReply: () => void;
	onForward: () => void;
	onEdit?: () => void;
	onPin?: () => void;
	/**
	 * True when the target message is currently pinned. Flips the
	 * "Pin Message" label to "Unpin Message" so the action mirrors
	 * its resulting state.
	 */
	isPinned?: boolean;
	onCopyText?: () => void;
	onInspect?: () => void;
	onDelete?: () => void;
}

export function MobileMessageActionsSheet({
	isOpen,
	onClose,
	isOwnMessage,
	canDelete,
	hasContent,
	onQuickReact,
	onAddReaction,
	onReply,
	onForward,
	onEdit,
	onPin,
	isPinned,
	onCopyText,
	onInspect,
	onDelete,
}: MobileMessageActionsSheetProps) {
	// Wrap each action so the sheet always closes after a selection.
	// Returning a no-arg handler keeps the JSX clean below.
	const wrap = (fn?: () => void) => () => {
		if (!fn) return;
		fn();
		onClose();
	};

	return (
		<BottomSheet
			isOpen={isOpen}
			onClose={onClose}
			disableDefaultHeader
			showHandle
			// Open at half height by default. The user can drag the
			// handle UP to expand toward the full sheet height if
			// they need to see all the actions, or down past the
			// threshold to dismiss.
			initialHeightSvh={50}
			expandable
		>
			<div className={styles.body}>
				{/* Quick emoji row */}
				<div className={styles.quickRow}>
					{QUICK_EMOJIS.map((qe) => (
						<button
							key={qe.name}
							type="button"
							className={styles.quickButton}
							onClick={() => {
								onQuickReact(qe.emoji);
								onClose();
							}}
							aria-label={`React with :${qe.name}:`}
						>
							<img
								src={`https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/svg/${emojiToCodepoint(qe.emoji)}.svg`}
								alt={qe.emoji}
								className={styles.quickEmoji}
								draggable={false}
							/>
						</button>
					))}
					<button
						type="button"
						className={styles.quickButton}
						onClick={wrap(onAddReaction)}
						aria-label="Add reaction"
					>
						<Plus size={22} weight="bold" />
					</button>
				</div>

				{/* Group 1 — Add Reaction lives alone so it visually
				    echoes the quick reactions row above it. */}
				<div className={styles.actionList}>
					<button type="button" className={styles.actionItem} onClick={wrap(onAddReaction)}>
						<Smiley size={20} weight="fill" />
						<span>Add Reaction</span>
					</button>
				</div>

				{/* Group 2 — message interaction actions (Reply /
				    Forward / Edit). Edit only shows on own messages. */}
				<div className={styles.actionList}>
					<button type="button" className={styles.actionItem} onClick={wrap(onReply)}>
						<ArrowBendUpLeft size={20} weight="fill" />
						<span>Reply</span>
					</button>
					<button type="button" className={styles.actionItem} onClick={wrap(onForward)}>
						<ArrowBendUpRight size={20} weight="fill" />
						<span>Forward</span>
					</button>
					{isOwnMessage && onEdit && (
						<button type="button" className={styles.actionItem} onClick={wrap(onEdit)}>
							<PencilSimple size={20} weight="fill" />
							<span>Edit Message</span>
						</button>
					)}
				</div>

				{/* Group 3 — mod / own-message actions (Pin / Delete).
				    Only renders when at least one of the two is
				    available, so viewers with no power on someone
				    else's message don't see an empty card. */}
				{(onPin || (canDelete && onDelete)) && (
					<div className={styles.actionList}>
						{onPin && (
							<button type="button" className={styles.actionItem} onClick={wrap(onPin)}>
								<PushPin size={20} weight="fill" />
								<span>{isPinned ? 'Unpin Message' : 'Pin Message'}</span>
							</button>
						)}
						{canDelete && onDelete && (
							<button
								type="button"
								className={`${styles.actionItem} ${styles.actionItemDanger}`}
								onClick={wrap(onDelete)}
							>
								<Trash size={20} weight="fill" />
								<span>Delete Message</span>
							</button>
						)}
					</div>
				)}

				{/* Group 4 — text / debug utilities (Copy Text +
				    Inspect Message). Copy Text is only shown when
				    there's actual text to copy — not for pure
				    attachment messages. */}
				{((hasContent && onCopyText) || onInspect) && (
					<div className={styles.actionList}>
						{hasContent && onCopyText && (
							<button type="button" className={styles.actionItem} onClick={wrap(onCopyText)}>
								<Copy size={20} weight="fill" />
								<span>Copy Text</span>
							</button>
						)}
						{onInspect && (
							<button type="button" className={styles.actionItem} onClick={wrap(onInspect)}>
								<MagnifyingGlass size={20} weight="fill" />
								<span>Inspect Message</span>
							</button>
						)}
					</div>
				)}
			</div>
		</BottomSheet>
	);
}
