/**
 * MobileMemberProfileSheet — mobile bottom sheet opened when tapping
 * a member row or a DM header. Ported from the new UI's sheet layout
 * and rebuilt against Convex: profile pulls from `api.auth.getPublicKeys`,
 * presence runs through `PresenceContext.resolveStatus`, and the roles
 * card uses `api.roles.listMembers` + `api.roles.list` for the live
 * assignment set.
 *
 *   ┌── handle ──┐
 *   │ [banner]   │    banner = accent color
 *   │ (avatar)  ⋯│    avatar lifts up to overlap banner
 *   │ Name       │
 *   │ @username  │
 *   │ [Edit Prof]│    (self only)
 *   │ ┌ About Me ┐│
 *   │ └──────────┘
 *   │ ┌ Roles    ┐│
 *   │ └──────────┘
 *   │ [Rotate Key] (DM only)
 *   └─────────────┘
 */
import { useMemo, useState } from 'react';
import { useMutation, useQuery } from 'convex/react';
import { useNavigate } from 'react-router-dom';
import { ChatCircleDots, DotsThree, Key, PencilSimple } from '@phosphor-icons/react';
import { Avatar, BottomSheet } from '@discord-clone/ui';
import { api } from '../../../../../convex/_generated/api';
import type { Id } from '../../../../../convex/_generated/dataModel';
import { useOnlineUsers } from '../../contexts/PresenceContext';
import styles from './MobileMemberProfileSheet.module.css';

interface MobileMemberProfileSheetMember {
	userId: string;
}

interface MobileMemberProfileSheetProps {
	isOpen: boolean;
	onClose: () => void;
	member: MobileMemberProfileSheetMember | null;
	/**
	 * Optional — when provided, a "Rotate Encryption Key" button is
	 * rendered below the action row. Only passed in from DM entry
	 * points so server-member sheets don't show it.
	 */
	onRotateKey?: () => Promise<void>;
}

const DEFAULT_ACCENT = '#4641D9';

function mapPresence(
	status: string | undefined,
): 'online' | 'idle' | 'dnd' | 'offline' {
	switch (status) {
		case 'online':
			return 'online';
		case 'idle':
			return 'idle';
		case 'dnd':
			return 'dnd';
		default:
			return 'offline';
	}
}

export function MobileMemberProfileSheet({
	isOpen,
	onClose,
	member,
	onRotateKey,
}: MobileMemberProfileSheetProps) {
	const navigate = useNavigate();
	const { resolveStatus } = useOnlineUsers();
	const [rotating, setRotating] = useState(false);
	const [rotateStatus, setRotateStatus] = useState<
		{ type: 'success' | 'error'; message: string } | null
	>(null);

	const allUsers = useQuery(api.auth.getPublicKeys, isOpen ? {} : 'skip') ?? [];
	const localUserId =
		typeof localStorage !== 'undefined' ? localStorage.getItem('userId') : null;

	const profile = useMemo(
		() => (member ? allUsers.find((u) => u.id === member.userId) : undefined),
		[allUsers, member],
	);

	const roleMembers = useQuery(api.roles.listMembers, isOpen ? {} : 'skip');
	const allRoles = useQuery(api.roles.list, isOpen ? {} : 'skip') ?? [];

	const assignedRoles = useMemo(() => {
		if (!member || !roleMembers) return [];
		const row = (roleMembers as any[]).find((r) => r.id === member.userId);
		if (!row) return [];
		const ids = new Set((row.roles as any[]).map((r) => r._id as string));
		return (allRoles as any[]).filter((r) => ids.has(r._id as string));
	}, [member, roleMembers, allRoles]);

	const openDM = useMutation(api.dms.openDM);

	if (!isOpen || !member) {
		return (
			<BottomSheet
				isOpen={isOpen}
				onClose={onClose}
				disableDefaultHeader
				showHandle={false}
				className={styles.sheet}
			>
				<div className={styles.root} />
			</BottomSheet>
		);
	}

	const displayName =
		profile?.displayName || profile?.username || 'Unknown User';
	const username = profile?.username || '';
	const avatarUrl = profile?.avatarUrl ?? null;
	const bio = profile?.aboutMe?.trim();
	const accent = (profile as any)?.accentColor || DEFAULT_ACCENT;
	const storedStatus = (profile?.status as string | undefined) || 'offline';
	const presence = mapPresence(resolveStatus(storedStatus, member.userId));

	const isMe = localUserId === member.userId;

	const handleEditProfile = () => {
		window.dispatchEvent(new CustomEvent('brycord:open-user-settings'));
		onClose();
	};

	const handleMessage = async () => {
		if (!localUserId) return;
		try {
			const result = await openDM({
				userId: localUserId as Id<'userProfiles'>,
				targetUserId: member.userId as Id<'userProfiles'>,
			});
			navigate(`/channels/@me/${result.channelId}`);
			onClose();
		} catch (err) {
			console.warn('Failed to open DM from sheet:', err);
		}
	};

	const handleRotate = async () => {
		if (!onRotateKey || rotating) return;
		setRotating(true);
		setRotateStatus(null);
		try {
			await onRotateKey();
			setRotateStatus({
				type: 'success',
				message: 'Encryption key rotated.',
			});
		} catch (err: any) {
			setRotateStatus({
				type: 'error',
				message: err?.message ?? 'Rotation failed.',
			});
		} finally {
			setRotating(false);
		}
	};

	return (
		<BottomSheet
			isOpen={isOpen}
			onClose={onClose}
			disableDefaultHeader
			showHandle={false}
			className={styles.sheet}
		>
			<div className={styles.root}>
				<div
					className={styles.banner}
					style={{ backgroundColor: accent }}
				>
					<div className={styles.bannerHandle} />
				</div>

				<div className={styles.headerRow}>
					<div className={styles.avatarWrap}>
						<Avatar
							src={avatarUrl}
							fallback={displayName}
							size={88}
							status={presence}
						/>
					</div>
					<button
						type="button"
						className={styles.moreButton}
						aria-label="More actions"
					>
						<DotsThree size={22} weight="bold" />
					</button>
				</div>

				<div className={styles.nameBlock}>
					<span className={styles.displayName}>{displayName}</span>
					{username && <span className={styles.handle}>@{username}</span>}
				</div>

				{isMe ? (
					<button
						type="button"
						className={styles.editProfileButton}
						onClick={handleEditProfile}
					>
						<PencilSimple size={18} weight="bold" />
						Edit Profile
					</button>
				) : (
					<button
						type="button"
						className={styles.editProfileButton}
						onClick={handleMessage}
					>
						<ChatCircleDots size={18} weight="bold" />
						Message
					</button>
				)}

				<div className={styles.cardStack}>
					{bio && (
						<div className={styles.card}>
							<div className={styles.cardTitleRow}>
								<span className={styles.cardTitle}>About Me</span>
							</div>
							<div
								style={{
									fontSize: 13,
									color: 'var(--text-secondary)',
									whiteSpace: 'pre-wrap',
									lineHeight: 1.45,
								}}
							>
								{bio}
							</div>
						</div>
					)}

					{assignedRoles.length > 0 && (
						<div className={styles.card}>
							<div className={styles.cardTitleRow}>
								<span className={styles.cardTitle}>Roles</span>
							</div>
							<div className={styles.rolesList}>
								{assignedRoles.map((role) => (
									<div key={role._id as string} className={styles.rolePill}>
										<span
											className={styles.roleDot}
											style={{
												backgroundColor:
													role.color || 'var(--text-primary-muted)',
											}}
										/>
										<span
											className={styles.roleName}
											style={role.color ? { color: role.color } : undefined}
										>
											{role.name}
										</span>
									</div>
								))}
							</div>
						</div>
					)}

					{!isMe && onRotateKey && (
						<div className={styles.card}>
							<div className={styles.cardTitleRow}>
								<span className={styles.cardTitle}>Encryption</span>
							</div>
							<div
								style={{
									fontSize: 12,
									color: 'var(--text-secondary)',
									marginBottom: 10,
								}}
							>
								Replace the key used to encrypt this DM. Existing messages
								stay readable; new messages use the new key.
							</div>
							<button
								type="button"
								className={styles.editProfileButton}
								onClick={handleRotate}
								disabled={rotating}
							>
								<Key size={18} weight="bold" />
								{rotating ? 'Rotating…' : 'Rotate Encryption Key'}
							</button>
							{rotateStatus && (
								<div
									style={{
										marginTop: 8,
										fontSize: 12,
										color:
											rotateStatus.type === 'success'
												? '#3ba55d'
												: 'var(--status-danger, #ed4245)',
									}}
								>
									{rotateStatus.message}
								</div>
							)}
						</div>
					)}
				</div>
			</div>
		</BottomSheet>
	);
}
