import { useEffect } from 'react';
import { observer } from 'mobx-react-lite';
import type { VoiceParticipantSnapshot } from '@brycord/matrix-client';
import VoiceStore from '@app/stores/VoiceStore';
import { VoiceGridLayout } from './VoiceGridLayout';
import { VoiceParticipantTile } from './VoiceParticipantTile';
import styles from './VoiceCallLayoutContent.module.css';

interface VoiceCallLayoutContentProps {
	participants: VoiceParticipantSnapshot[];
}

/**
 * Switches between grid layout (no screen share currently being
 * WATCHED) and focus layout (the local user is actively watching
 * a screen share — large primary tile + carousel of everyone else).
 *
 * The trigger changed with the opt-in streaming rework: previously
 * any peer screen-sharing auto-flipped us into focus mode. Now we
 * require the local user to explicitly click "Watch Stream" first
 * — `p.hasScreenPublication` means the peer is sharing, but
 * `p.screenSubscribed` is only true once the user opts in. This
 * keeps the layout calm when multiple peers share simultaneously
 * and lets the user pick which one to focus.
 */
export const VoiceCallLayoutContent = observer(function VoiceCallLayoutContent({
	participants,
}: VoiceCallLayoutContentProps) {
	const focusedScreenSharer = participants.find(
		(p) => p.hasScreenPublication && p.screenSubscribed,
	);

	// Flip the focused screen share to HIGH quality whenever it
	// enters focus mode, and implicitly leave it alone (or get
	// downgraded by leaving the watch set entirely) when the user
	// unwatches. Runs only when the focused identity actually
	// changes so we don't re-call setVideoQuality on every render.
	const focusedIdentity = focusedScreenSharer?.identity;
	useEffect(() => {
		if (!focusedIdentity) return;
		VoiceStore.setStreamQuality(focusedIdentity, 'screen', 'high');
	}, [focusedIdentity]);

	if (!focusedScreenSharer) {
		return <VoiceGridLayout participants={participants} />;
	}

	// Build the carousel items the same way the grid does: a camera
	// tile per participant, plus an extra screen-share tile for any
	// other peer who is also sharing their screen. The currently-
	// focused screen share is excluded from the carousel since it's
	// already rendering in the main slot — otherwise it would show
	// up twice.
	const carouselItems: {
		key: string;
		participant: VoiceParticipantSnapshot;
		showScreenShare: boolean;
	}[] = [];
	for (const p of participants) {
		carouselItems.push({
			key: `${p.identity}|camera`,
			participant: p,
			showScreenShare: false,
		});
		if (p.hasScreenPublication && p.identity !== focusedScreenSharer.identity) {
			carouselItems.push({
				key: `${p.identity}|screen`,
				participant: p,
				showScreenShare: true,
			});
		}
	}

	// Focus mode — large screen tile + carousel of all participants
	return (
		<div className={styles.focusLayoutContent}>
			<div className={styles.focusLayoutMain}>
				<VoiceParticipantTile participant={focusedScreenSharer} showScreenShare />
			</div>
			<div className={styles.carouselWrapper}>
				<div className={styles.carousel}>
					{carouselItems.map((item) => (
						<div key={item.key} className={styles.carouselItem}>
							<VoiceParticipantTile
								participant={item.participant}
								showScreenShare={item.showScreenShare}
							/>
						</div>
					))}
				</div>
			</div>
		</div>
	);
});
