import { useQuery } from 'convex/react';
import { SpeakerHigh } from '@phosphor-icons/react';
import { useState } from 'react';
import { useParams } from 'react-router-dom';
import { api } from '../../../../../convex/_generated/api';
import { useVoice } from '../../contexts/VoiceContext';
import { useIsNarrowScreen } from '../../hooks/useIsNarrowScreen';
import { ChannelChatLayout } from './ChannelChatLayout';
import { ChannelDetailsDrawer } from './ChannelDetailsDrawer';
import { ChannelHeader } from './ChannelHeader';
import { MemberListContainer } from '../member/MemberListContainer';
import { SearchPanel } from './SearchPanel';
import { VoiceCallView } from '../voice/VoiceCallView';
import styles from './ChannelView.module.css';

/**
 * ChannelView — the main content column for a selected channel. Shows
 * either the voice-join prompt, an active voice call, or a text chat
 * (header + messages + textarea + members panel).
 */
export function ChannelView() {
	const { channelId } = useParams<{ channelId: string }>();
	const voice = useVoice();
	const [membersVisible, setMembersVisible] = useState(true);
	const [detailsOpen, setDetailsOpen] = useState(false);
	const [searchQuery, setSearchQuery] = useState('');
	const isNarrow = useIsNarrowScreen();
	const showMembers = membersVisible && !isNarrow;
	const searchOpen = searchQuery.trim().length > 0;

	const channel = useQuery(
		api.channels.get,
		channelId ? { id: channelId as any } : 'skip',
	);

	if (!channelId) return null;

	const isVoiceChannel = channel?.type === 'voice';
	const isDM = channel?.type === 'dm';
	const isInThisVoiceCall = voice?.activeChannelId === channelId;

	// DMs never show a members panel — there are only two participants
	// and they're already represented by the DM header + yourself.
	const showMembersPanel = showMembers && !isDM;

	const handleJoinVoice = () => {
		if (!voice || !channel) return;
		const myId = typeof localStorage !== 'undefined' ? localStorage.getItem('userId') : null;
		if (!myId) return;
		void voice.connectToVoice?.(channelId, channel.name, myId, false);
	};

	return (
		<div className={styles.container}>
			{/* Voice channels we're actively in skip the chat-style header
			    entirely — the search bar, pins button, members toggle,
			    and topic string all belong to text channels. A voice call
			    owns the whole surface via VoiceCallView so there's no
			    room for that chrome anyway. */}
			{(!isVoiceChannel || !isInThisVoiceCall) && (
				<ChannelHeader
					channel={channel as any}
					serverId={undefined}
					onOpenChannelDetails={() => setDetailsOpen(true)}
					onOpenSearchDrawer={() => {}}
					membersVisible={showMembersPanel}
					onToggleMembers={() => setMembersVisible((v) => !v)}
					hideMembersButton={isDM}
					isNarrow={isNarrow}
					searchQuery={searchQuery}
					onSearchChange={setSearchQuery}
					onSearchClear={() => setSearchQuery('')}
				/>
			)}
			<div className={styles.body}>
				{isVoiceChannel ? (
					isInThisVoiceCall ? (
						<VoiceCallView channelId={channelId} />
					) : (
						<div className={styles.voiceJoinPrompt}>
							<SpeakerHigh size={64} weight="fill" className={styles.voiceJoinIcon} />
							<h2 className={styles.voiceJoinTitle}>{channel?.name || 'Voice Channel'}</h2>
							<p className={styles.voiceJoinDescription}>Click below to join the voice channel.</p>
							<button className={styles.voiceJoinButton} onClick={handleJoinVoice}>
								Join Voice
							</button>
						</div>
					)
				) : (
					<>
						<ChannelChatLayout channelId={channelId} />
						{searchOpen ? (
							<>
								<div className={styles.memberListDivider} />
								<SearchPanel
									channelId={channelId}
									query={searchQuery}
									onClose={() => setSearchQuery('')}
								/>
							</>
						) : (
							showMembersPanel && (
								<>
									<div className={styles.memberListDivider} />
									<MemberListContainer
										members={[]}
										channelId={channelId}
										serverId={undefined}
									/>
								</>
							)
						)}
					</>
				)}
			</div>
			<ChannelDetailsDrawer
				isOpen={detailsOpen}
				onClose={() => setDetailsOpen(false)}
				channelId={channelId}
				channelName={channel?.name}
				channelType={channel?.type}
			/>
		</div>
	);
}
