/**
 * MobileUserSettings — full-screen stand-in for UserSettingsModal on
 * mobile. Ported from the new UI: top bar with X / back button, a
 * user-avatar hero on the category list, then grouped rounded cards
 * listing each tab. Tapping a row replaces the body with that tab's
 * content and the top bar's X swaps for a back arrow.
 *
 * Reuses the existing tab components (`AccountTab`, `AppearanceTab`,
 * `VoiceTab`, `SecurityTab`, plus `KeybindsTab`) exported from
 * UserSettingsModal so the underlying form logic — profile editing,
 * avatar upload, accent color, voice test, recovery key — is
 * identical to desktop.
 */
import { useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { useQuery } from 'convex/react';
import {
	Bell,
	CaretLeft,
	CaretRight,
	Microphone,
	PaintBrush,
	ShieldCheck,
	SignOut,
	User as UserIcon,
	X,
} from '@phosphor-icons/react';
import { Avatar } from '@discord-clone/ui';
import { api } from '../../../../../convex/_generated/api';
import { useOnlineUsers } from '../../contexts/PresenceContext';
import { useLogout } from '../../hooks/useLogout';
import { LogoutConfirmModal } from '../modals/LogoutConfirmModal';
import {
	AccountTab,
	AppearanceTab,
	SecurityTab,
	VoiceTab,
} from './UserSettingsModal';
import styles from './MobileUserSettings.module.css';

// Keybinds are deliberately omitted from the mobile settings — mobile
// doesn't have a physical keyboard workflow, so the whole tab would
// be dead weight. Desktop still shows it via UserSettingsModal.
type TabId =
	| 'account'
	| 'appearance'
	| 'voice'
	| 'notifications'
	| 'security';

interface MobileUserSettingsProps {
	isOpen: boolean;
	onClose: () => void;
	initialTab?: TabId;
}

interface MobileSettingsTabMeta {
	id: TabId;
	label: string;
	icon: React.ComponentType<{
		size?: number;
		weight?: 'regular' | 'fill' | 'bold';
	}>;
}

interface MobileSettingsGroup {
	category: string;
	tabs: MobileSettingsTabMeta[];
}

const TAB_GROUPS: MobileSettingsGroup[] = [
	{
		category: 'Your Account',
		tabs: [
			{ id: 'account', label: 'My Account', icon: UserIcon },
			{ id: 'security', label: 'Security & Login', icon: ShieldCheck },
		],
	},
	{
		category: 'App Settings',
		tabs: [
			{ id: 'appearance', label: 'Appearance', icon: PaintBrush },
			{ id: 'voice', label: 'Voice & Video', icon: Microphone },
			{ id: 'notifications', label: 'Notifications', icon: Bell },
		],
	},
];

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 MobileUserSettings({
	isOpen,
	onClose,
	initialTab,
}: MobileUserSettingsProps) {
	// `null` means we're on the category list. A non-null tab id
	// shows that tab's panel full-screen with a back arrow in the
	// top bar.
	const [activeTab, setActiveTab] = useState<TabId | null>(
		initialTab ?? null,
	);
	const logout = useLogout();
	const [showLogoutConfirm, setShowLogoutConfirm] = useState(false);

	useEffect(() => {
		if (isOpen) setActiveTab(initialTab ?? null);
	}, [isOpen, initialTab]);

	// Lock body scroll while the overlay is open.
	useEffect(() => {
		if (!isOpen) return;
		const prev = document.body.style.overflow;
		document.body.style.overflow = 'hidden';
		return () => {
			document.body.style.overflow = prev;
		};
	}, [isOpen]);

	// Escape — pop one level (panel → list → close).
	useEffect(() => {
		if (!isOpen) return;
		const handler = (e: KeyboardEvent) => {
			if (e.key !== 'Escape') return;
			if (activeTab !== null) setActiveTab(null);
			else onClose();
		};
		document.addEventListener('keydown', handler);
		return () => document.removeEventListener('keydown', handler);
	}, [isOpen, activeTab, onClose]);

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

	if (!isOpen) return null;

	const displayName = me?.displayName || me?.username || 'You';
	const username = me?.username || '';
	const avatarUrl = me?.avatarUrl ?? null;
	const presence = mapPresence(
		localUserId
			? resolveStatus(me?.status ?? 'offline', localUserId)
			: 'offline',
	);

	const allTabs = TAB_GROUPS.flatMap((g) => g.tabs);
	const activeMeta = activeTab ? allTabs.find((t) => t.id === activeTab) : undefined;

	const goBack = () => setActiveTab(null);
	const backIsClose = activeTab === null;

	const renderPanel = () => {
		switch (activeTab) {
			case 'account':
				return <AccountTab />;
			case 'security':
				return <SecurityTab />;
			case 'voice':
				return <VoiceTab />;
			case 'appearance':
				return <AppearanceTab />;
			case 'notifications':
				return (
					<div>
						<h2 className={styles.stubTitle}>Notifications</h2>
						<p className={styles.stubBody}>
							Notification settings coming soon.
						</p>
					</div>
				);
			default:
				return null;
		}
	};

	return createPortal(
		<>
		<div className={styles.overlay} role="dialog" aria-modal="true">
			<div className={styles.topBar}>
				<button
					type="button"
					className={styles.topBarButton}
					onClick={backIsClose ? onClose : goBack}
					aria-label={backIsClose ? 'Close' : 'Back'}
				>
					{backIsClose ? (
						<X size={22} weight="bold" />
					) : (
						<CaretLeft size={22} weight="bold" />
					)}
				</button>
				<div className={styles.topBarTitleBlock}>
					<h2 className={styles.topBarTitle}>
						{activeMeta ? activeMeta.label : 'Settings'}
					</h2>
				</div>
				<div />
			</div>

			{activeTab === null ? (
				<div className={`${styles.body} ${styles.bodyList}`}>
					<div className={styles.hero}>
						<Avatar
							src={avatarUrl}
							fallback={displayName}
							size={88}
							status={presence}
						/>
						<h3 className={styles.heroName}>{displayName}</h3>
						{username && <p className={styles.heroHandle}>@{username}</p>}
					</div>

					{TAB_GROUPS.map((group) => (
						<div key={group.category} className={styles.section}>
							<div className={styles.sectionLabel}>{group.category}</div>
							<div className={styles.tabList}>
								{group.tabs.map((tab) => {
									const Icon = tab.icon;
									return (
										<button
											key={tab.id}
											type="button"
											className={styles.tabItem}
											onClick={() => setActiveTab(tab.id)}
										>
											<span className={styles.tabItemIcon}>
												<Icon size={18} weight="fill" />
											</span>
											<span>{tab.label}</span>
											<CaretRight
												size={16}
												weight="bold"
												className={styles.tabItemCaret}
											/>
										</button>
									);
								})}
							</div>
						</div>
					))}

					<div className={styles.section}>
						<div className={styles.dangerCard}>
							<button
								type="button"
								className={styles.dangerItem}
								onClick={() => setShowLogoutConfirm(true)}
							>
								<span className={styles.dangerItemIcon}>
									<SignOut size={18} weight="fill" />
								</span>
								<span>Log Out</span>
							</button>
						</div>
					</div>
				</div>
			) : (
				<div className={`${styles.body} ${styles.bodyPanel}`}>
					{renderPanel()}
				</div>
			)}
		</div>
		<LogoutConfirmModal
			isOpen={showLogoutConfirm}
			onClose={() => setShowLogoutConfirm(false)}
			onConfirm={() => {
				setShowLogoutConfirm(false);
				void logout();
			}}
		/>
		</>,
		document.body,
	);
}
