/* eslint-disable no-console */
import React, { useCallback, useEffect, useRef, useState, MouseEventHandler } from 'react';
import { Box, Button, color, config, Header, IconButton, Input, Menu, MenuItem, PopOut, RectCords, Scroll, Switch, Text, toRem } from 'folds';
import { Icon, Icons } from '../../../components/icons';
import FocusTrap from 'focus-trap-react';
import { Page, PageContent, PageHeader } from '../../../components/page';
import { SequenceCard } from '../../../components/sequence-card';
import { SettingTile } from '../../../components/setting-tile';
import { SequenceCardStyle } from '../styles.css';
import { stopPropagation } from '../../../utils/keyboard';
import { useSetting } from '../../../state/hooks/settings';
import { settingsAtom } from '../../../state/settings';

/** Represents an audio device (microphone or speaker) */
interface AudioDevice {
  deviceId: string;
  label: string;
  kind: MediaDeviceKind;
}

/** Screen share resolution presets */
export type ScreenShareResolution = '720p' | '1080p' | '1440p' | '4k' | 'source';

/** Screen share resolution configs */
export const SCREEN_SHARE_RESOLUTIONS: Record<ScreenShareResolution, { width: number; height: number; label: string }> = {
  '720p': { width: 1280, height: 720, label: '720p (HD)' },
  '1080p': { width: 1920, height: 1080, label: '1080p (Full HD)' },
  '1440p': { width: 2560, height: 1440, label: '1440p (2K)' },
  '4k': { width: 3840, height: 2160, label: '4K (Ultra HD)' },
  'source': { width: 0, height: 0, label: 'Source Resolution' },
};

/** Screen share bitrate presets in kbps */
export type ScreenShareBitrate = 'low' | 'medium' | 'high' | 'ultra';

/** Screen share bitrate configs */
export const SCREEN_SHARE_BITRATES: Record<ScreenShareBitrate, { bitrate: number; label: string }> = {
  'low': { bitrate: 1000, label: 'Low (1 Mbps)' },
  'medium': { bitrate: 2500, label: 'Medium (2.5 Mbps)' },
  'high': { bitrate: 5000, label: 'High (5 Mbps)' },
  'ultra': { bitrate: 10000, label: 'Ultra (10 Mbps)' },
};

/** Stored audio device settings */
interface AudioSettings {
  microphoneId: string | null;
  speakerId: string | null;
  noiseSuppression: boolean;
  echoCancellation: boolean;
  autoGainControl: boolean;
  screenShareResolution: ScreenShareResolution;
  screenShareBitrate: ScreenShareBitrate;
  screenShareFrameRate: number;
}

const AUDIO_SETTINGS_KEY = 'cinny_audio_settings';

/** Default audio settings */
const DEFAULT_AUDIO_SETTINGS: AudioSettings = {
  microphoneId: null,
  speakerId: null,
  noiseSuppression: true,
  echoCancellation: true,
  autoGainControl: true,
  screenShareResolution: '1080p',
  screenShareBitrate: 'high',
  screenShareFrameRate: 30,
};

/**
 * Loads audio settings from localStorage
 * @returns The stored audio settings or defaults
 */
function loadAudioSettings(): AudioSettings {
  try {
    const stored = localStorage.getItem(AUDIO_SETTINGS_KEY);
    if (stored) {
      return { ...DEFAULT_AUDIO_SETTINGS, ...JSON.parse(stored) };
    }
  } catch (e) {
    console.error('Failed to load audio settings:', e);
  }
  return DEFAULT_AUDIO_SETTINGS;
}

/** Dispatched on window after audio settings are persisted. */
export const AUDIO_SETTINGS_CHANGED_EVENT = 'paarrot-audio-settings-changed';

/**
 * Saves audio settings to localStorage
 * @param settings - The audio settings to save
 */
function saveAudioSettings(settings: AudioSettings): void {
  try {
    localStorage.setItem(AUDIO_SETTINGS_KEY, JSON.stringify(settings));
    window.dispatchEvent(new CustomEvent(AUDIO_SETTINGS_CHANGED_EVENT));
  } catch (e) {
    console.error('Failed to save audio settings:', e);
  }
}

/**
 * Gets the currently stored audio settings
 * @returns The stored audio settings
 */
export function getAudioSettings(): AudioSettings {
  return loadAudioSettings();
}

/**
 * LiveKit / getUserMedia capture options from stored settings.
 * Always sets voiceIsolation explicitly — LiveKit 2.20 defaults it to true,
 * which overrides noiseSuppression when left unset.
 */
export function getAudioCaptureOptions(): {
  deviceId?: string;
  noiseSuppression: boolean;
  echoCancellation: boolean;
  autoGainControl: boolean;
  voiceIsolation: boolean;
} {
  const settings = getAudioSettings();
  return {
    deviceId: settings.microphoneId || undefined,
    noiseSuppression: settings.noiseSuppression,
    echoCancellation: settings.echoCancellation,
    autoGainControl: settings.autoGainControl,
    voiceIsolation: settings.noiseSuppression,
  };
}

/** MediaTrackConstraints for getUserMedia / applyConstraints from UI settings. */
function getMicTrackConstraints(settings: AudioSettings): MediaTrackConstraints {
  return {
    ...(settings.microphoneId ? { deviceId: { exact: settings.microphoneId } } : {}),
    noiseSuppression: settings.noiseSuppression,
    echoCancellation: settings.echoCancellation,
    autoGainControl: settings.autoGainControl,
    // Experimental; Chromium / Electron. Keep in sync with noise suppression.
    voiceIsolation: settings.noiseSuppression,
  } as MediaTrackConstraints;
}

type DeviceSelectorProps = {
  devices: AudioDevice[];
  selectedId: string | null;
  onSelect: (deviceId: string) => void;
};

/**
 * Dropdown menu for selecting an audio device
 */
function DeviceSelector({ devices, selectedId, onSelect }: DeviceSelectorProps) {
  return (
    <Menu>
      <Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
        {devices.length === 0 ? (
          <MenuItem size="300" variant="Surface" radii="300" disabled>
            <Text size="T300">No devices found</Text>
          </MenuItem>
        ) : (
          devices.map((device) => (
            <MenuItem
              key={device.deviceId}
              size="300"
              variant={device.deviceId === selectedId ? 'Primary' : 'Surface'}
              radii="300"
              onClick={() => onSelect(device.deviceId)}
            >
              <Text size="T300" truncate>
                {device.label || `Unknown Device (${device.deviceId.slice(0, 8)}...)`}
              </Text>
            </MenuItem>
          ))
        )}
      </Box>
    </Menu>
  );
}

type DeviceSelectButtonProps = {
  devices: AudioDevice[];
  selectedId: string | null;
  onSelect: (deviceId: string) => void;
};

/**
 * Button that opens a device selection dropdown
 */
function DeviceSelectButton({ devices, selectedId, onSelect }: DeviceSelectButtonProps) {
  const [menuCords, setMenuCords] = useState<RectCords>();
  const selectedDevice = devices.find((d) => d.deviceId === selectedId);
  const displayLabel = selectedDevice?.label || selectedDevice?.deviceId.slice(0, 8) || 'Default';

  const handleClick: MouseEventHandler<HTMLButtonElement> = (evt) => {
    setMenuCords(evt.currentTarget.getBoundingClientRect());
  };

  const handleSelect = (deviceId: string) => {
    onSelect(deviceId);
    setMenuCords(undefined);
  };

  return (
    <>
      <Button
        size="300"
        variant="Primary"
        outlined
        fill="Soft"
        radii="300"
        after={<Icon size="300" src={Icons.ChevronBottom} />}
        onClick={handleClick}
        style={{ maxWidth: toRem(250) }}
      >
        <Text size="T300" truncate>
          {displayLabel}
        </Text>
      </Button>
      <PopOut
        anchor={menuCords}
        offset={5}
        position="Bottom"
        align="End"
        content={
          <FocusTrap
            focusTrapOptions={{
              initialFocus: false,
              onDeactivate: () => setMenuCords(undefined),
              clickOutsideDeactivates: true,
              isKeyForward: (evt: KeyboardEvent) =>
                evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
              isKeyBackward: (evt: KeyboardEvent) =>
                evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
              escapeDeactivates: stopPropagation,
            }}
          >
            <DeviceSelector
              devices={devices}
              selectedId={selectedId}
              onSelect={handleSelect}
            />
          </FocusTrap>
        }
      />
    </>
  );
}

type ScreenShareResolutionSelectProps = {
  value: ScreenShareResolution;
  onChange: (value: ScreenShareResolution) => void;
};

/**
 * Dropdown for selecting screen share resolution
 */
function ScreenShareResolutionSelect({ value, onChange }: ScreenShareResolutionSelectProps) {
  const [menuCords, setMenuCords] = useState<RectCords>();

  const handleClick: MouseEventHandler<HTMLButtonElement> = (evt) => {
    setMenuCords(evt.currentTarget.getBoundingClientRect());
  };

  const handleSelect = (resolution: ScreenShareResolution) => {
    onChange(resolution);
    setMenuCords(undefined);
  };

  return (
    <>
      <Button
        size="300"
        variant="Primary"
        outlined
        fill="Soft"
        radii="300"
        after={<Icon size="300" src={Icons.ChevronBottom} />}
        onClick={handleClick}
        style={{ maxWidth: toRem(200) }}
      >
        <Text size="T300">{SCREEN_SHARE_RESOLUTIONS[value].label}</Text>
      </Button>
      <PopOut
        anchor={menuCords}
        offset={5}
        position="Bottom"
        align="End"
        content={
          <FocusTrap
            focusTrapOptions={{
              initialFocus: false,
              onDeactivate: () => setMenuCords(undefined),
              clickOutsideDeactivates: true,
              escapeDeactivates: stopPropagation,
            }}
          >
            <Menu>
              <Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
                {(Object.keys(SCREEN_SHARE_RESOLUTIONS) as ScreenShareResolution[]).map((res) => (
                  <MenuItem
                    key={res}
                    size="300"
                    variant={res === value ? 'Primary' : 'Surface'}
                    radii="300"
                    onClick={() => handleSelect(res)}
                  >
                    <Text size="T300">{SCREEN_SHARE_RESOLUTIONS[res].label}</Text>
                  </MenuItem>
                ))}
              </Box>
            </Menu>
          </FocusTrap>
        }
      />
    </>
  );
}

type ScreenShareBitrateSelectProps = {
  value: ScreenShareBitrate;
  onChange: (value: ScreenShareBitrate) => void;
};

/**
 * Dropdown for selecting screen share bitrate
 */
function ScreenShareBitrateSelect({ value, onChange }: ScreenShareBitrateSelectProps) {
  const [menuCords, setMenuCords] = useState<RectCords>();

  const handleClick: MouseEventHandler<HTMLButtonElement> = (evt) => {
    setMenuCords(evt.currentTarget.getBoundingClientRect());
  };

  const handleSelect = (bitrate: ScreenShareBitrate) => {
    onChange(bitrate);
    setMenuCords(undefined);
  };

  return (
    <>
      <Button
        size="300"
        variant="Primary"
        outlined
        fill="Soft"
        radii="300"
        after={<Icon size="300" src={Icons.ChevronBottom} />}
        onClick={handleClick}
        style={{ maxWidth: toRem(200) }}
      >
        <Text size="T300">{SCREEN_SHARE_BITRATES[value].label}</Text>
      </Button>
      <PopOut
        anchor={menuCords}
        offset={5}
        position="Bottom"
        align="End"
        content={
          <FocusTrap
            focusTrapOptions={{
              initialFocus: false,
              onDeactivate: () => setMenuCords(undefined),
              clickOutsideDeactivates: true,
              escapeDeactivates: stopPropagation,
            }}
          >
            <Menu>
              <Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
                {(Object.keys(SCREEN_SHARE_BITRATES) as ScreenShareBitrate[]).map((br) => (
                  <MenuItem
                    key={br}
                    size="300"
                    variant={br === value ? 'Primary' : 'Surface'}
                    radii="300"
                    onClick={() => handleSelect(br)}
                  >
                    <Text size="T300">{SCREEN_SHARE_BITRATES[br].label}</Text>
                  </MenuItem>
                ))}
              </Box>
            </Menu>
          </FocusTrap>
        }
      />
    </>
  );
}

type ScreenShareFrameRateSelectProps = {
  value: number;
  onChange: (value: number) => void;
};

const FRAME_RATES = [15, 24, 30, 60];

/**
 * Dropdown for selecting screen share frame rate
 */
function ScreenShareFrameRateSelect({ value, onChange }: ScreenShareFrameRateSelectProps) {
  const [menuCords, setMenuCords] = useState<RectCords>();

  const handleClick: MouseEventHandler<HTMLButtonElement> = (evt) => {
    setMenuCords(evt.currentTarget.getBoundingClientRect());
  };

  const handleSelect = (frameRate: number) => {
    onChange(frameRate);
    setMenuCords(undefined);
  };

  return (
    <>
      <Button
        size="300"
        variant="Primary"
        outlined
        fill="Soft"
        radii="300"
        after={<Icon size="300" src={Icons.ChevronBottom} />}
        onClick={handleClick}
        style={{ maxWidth: toRem(200) }}
      >
        <Text size="T300">{value} FPS</Text>
      </Button>
      <PopOut
        anchor={menuCords}
        offset={5}
        position="Bottom"
        align="End"
        content={
          <FocusTrap
            focusTrapOptions={{
              initialFocus: false,
              onDeactivate: () => setMenuCords(undefined),
              clickOutsideDeactivates: true,
              escapeDeactivates: stopPropagation,
            }}
          >
            <Menu>
              <Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
                {FRAME_RATES.map((fr) => (
                  <MenuItem
                    key={fr}
                    size="300"
                    variant={fr === value ? 'Primary' : 'Surface'}
                    radii="300"
                    onClick={() => handleSelect(fr)}
                  >
                    <Text size="T300">{fr} FPS</Text>
                  </MenuItem>
                ))}
              </Box>
            </Menu>
          </FocusTrap>
        }
      />
    </>
  );
}

type AudioProps = {
  requestClose: () => void;
};

/**
 * Audio settings page component
 * Allows users to select microphone and speaker devices for calls
 */
export function Audio({ requestClose }: AudioProps) {
  const [microphones, setMicrophones] = useState<AudioDevice[]>([]);
  const [speakers, setSpeakers] = useState<AudioDevice[]>([]);
  const [settings, setSettings] = useState<AudioSettings>(loadAudioSettings);
  const [permissionStatus, setPermissionStatus] = useState<'granted' | 'denied' | 'prompt'>('prompt');
  const [micTestState, setMicTestState] = useState<'idle' | 'testing' | 'done' | 'error'>('idle');
  const [micLevel, setMicLevel] = useState(0);
  const [speakerTestState, setSpeakerTestState] = useState<'idle' | 'testing' | 'done' | 'error'>('idle');
  const [micMonitoring, setMicMonitoring] = useState(false);
  const micAnimFrameRef = useRef<number | null>(null);
  const micMonitorContextRef = useRef<AudioContext | null>(null);
  const micMonitorStreamRef = useRef<MediaStream | null>(null);
  const micMonitorGainRef = useRef<GainNode | null>(null);
  const [showRemoteCursor, setShowRemoteCursor] = useSetting(settingsAtom, 'showRemoteCursor');

  useEffect(() => {
    const loadDevices = async () => {
      try {
        // Request permission to access media devices
        await navigator.mediaDevices.getUserMedia({ audio: true });
        setPermissionStatus('granted');

        const devices = await navigator.mediaDevices.enumerateDevices();
        
        const mics = devices
          .filter((d) => d.kind === 'audioinput')
          .map((d) => ({
            deviceId: d.deviceId,
            label: d.label,
            kind: d.kind,
          }));
        
        const spks = devices
          .filter((d) => d.kind === 'audiooutput')
          .map((d) => ({
            deviceId: d.deviceId,
            label: d.label,
            kind: d.kind,
          }));

        setMicrophones(mics);
        setSpeakers(spks);

        // If no device is selected yet, use the first available
        if (!settings.microphoneId && mics.length > 0) {
          setSettings((prev) => ({ ...prev, microphoneId: mics[0].deviceId }));
        }
        if (!settings.speakerId && spks.length > 0) {
          setSettings((prev) => ({ ...prev, speakerId: spks[0].deviceId }));
        }
      } catch (e) {
        console.error('Failed to enumerate devices:', e);
        setPermissionStatus('denied');
      }
    };

    loadDevices();

    // Listen for device changes
    const handleDeviceChange = () => {
      loadDevices();
    };
    navigator.mediaDevices.addEventListener('devicechange', handleDeviceChange);

    return () => {
      navigator.mediaDevices.removeEventListener('devicechange', handleDeviceChange);
    };
  }, [settings.microphoneId, settings.speakerId]);

  const handleMicrophoneSelect = (deviceId: string) => {
    const newSettings = { ...settings, microphoneId: deviceId };
    setSettings(newSettings);
    saveAudioSettings(newSettings);
  };

  const handleSpeakerSelect = (deviceId: string) => {
    const newSettings = { ...settings, speakerId: deviceId };
    setSettings(newSettings);
    saveAudioSettings(newSettings);
  };

  const handleNoiseSuppressionChange = (enabled: boolean) => {
    const newSettings = { ...settings, noiseSuppression: enabled };
    setSettings(newSettings);
    saveAudioSettings(newSettings);
  };

  const handleEchoCancellationChange = (enabled: boolean) => {
    const newSettings = { ...settings, echoCancellation: enabled };
    setSettings(newSettings);
    saveAudioSettings(newSettings);
  };

  const handleAutoGainControlChange = (enabled: boolean) => {
    const newSettings = { ...settings, autoGainControl: enabled };
    setSettings(newSettings);
    saveAudioSettings(newSettings);
  };

  const handleScreenShareResolutionChange = (resolution: ScreenShareResolution) => {
    const newSettings = { ...settings, screenShareResolution: resolution };
    setSettings(newSettings);
    saveAudioSettings(newSettings);
  };

  const handleScreenShareBitrateChange = (bitrate: ScreenShareBitrate) => {
    const newSettings = { ...settings, screenShareBitrate: bitrate };
    setSettings(newSettings);
    saveAudioSettings(newSettings);
  };

  const handleScreenShareFrameRateChange = (frameRate: number) => {
    const newSettings = { ...settings, screenShareFrameRate: frameRate };
    setSettings(newSettings);
    saveAudioSettings(newSettings);
  };

  const handleTestMicrophone = useCallback(async () => {
    if (micTestState === 'testing') return;
    setMicTestState('testing');
    setMicLevel(0);
    try {
      const stream = await navigator.mediaDevices.getUserMedia({
        audio: settings.microphoneId ? { deviceId: { exact: settings.microphoneId } } : true,
      });
      const audioContext = new AudioContext();
      const analyser = audioContext.createAnalyser();
      analyser.fftSize = 256;
      const dataArray = new Uint8Array(analyser.frequencyBinCount);
      const microphone = audioContext.createMediaStreamSource(stream);
      microphone.connect(analyser);

      const tick = () => {
        analyser.getByteFrequencyData(dataArray);
        const avg = dataArray.reduce((a, b) => a + b, 0) / dataArray.length;
        setMicLevel(Math.min(100, Math.round((avg / 255) * 100 * 3)));
        micAnimFrameRef.current = requestAnimationFrame(tick);
      };
      micAnimFrameRef.current = requestAnimationFrame(tick);

      setTimeout(() => {
        if (micAnimFrameRef.current !== null) {
          cancelAnimationFrame(micAnimFrameRef.current);
          micAnimFrameRef.current = null;
        }
        stream.getTracks().forEach((track) => track.stop());
        audioContext.close();
        setMicLevel(0);
        setMicTestState('done');
        setTimeout(() => setMicTestState('idle'), 2000);
      }, 3000);
    } catch (e) {
      console.error('Microphone test failed:', e);
      setMicTestState('error');
      setTimeout(() => setMicTestState('idle'), 2000);
    }
  }, [micTestState, settings.microphoneId]);

  const handleTestSpeaker = useCallback(async () => {
    if (speakerTestState === 'testing') return;
    setSpeakerTestState('testing');
    try {
      const audioContext = new AudioContext();
      const oscillator = audioContext.createOscillator();
      const gainNode = audioContext.createGain();
      oscillator.connect(gainNode);
      gainNode.connect(audioContext.destination);
      oscillator.frequency.value = 440;
      gainNode.gain.setValueAtTime(0, audioContext.currentTime);
      gainNode.gain.linearRampToValueAtTime(0.15, audioContext.currentTime + 0.1);
      gainNode.gain.linearRampToValueAtTime(0, audioContext.currentTime + 1.0);
      oscillator.start();
      oscillator.stop(audioContext.currentTime + 1.0);
      setTimeout(() => {
        audioContext.close();
        setSpeakerTestState('done');
        setTimeout(() => setSpeakerTestState('idle'), 2000);
      }, 1200);
    } catch (e) {
      console.error('Speaker test failed:', e);
      setSpeakerTestState('error');
      setTimeout(() => setSpeakerTestState('idle'), 2000);
    }
  }, [speakerTestState]);

  const handleMicMonitoringToggle = useCallback(async () => {
    if (micMonitoring) {
      // Stop monitoring
      if (micAnimFrameRef.current !== null) {
        cancelAnimationFrame(micAnimFrameRef.current);
        micAnimFrameRef.current = null;
      }
      if (micMonitorStreamRef.current) {
        micMonitorStreamRef.current.getTracks().forEach((track) => track.stop());
        micMonitorStreamRef.current = null;
      }
      if (micMonitorContextRef.current) {
        micMonitorContextRef.current.close();
        micMonitorContextRef.current = null;
      }
      micMonitorGainRef.current = null;
      setMicLevel(0);
      setMicMonitoring(false);
    } else {
      // Start monitoring
      try {
        const stream = await navigator.mediaDevices.getUserMedia({
          audio: getMicTrackConstraints(settings),
        });
        const audioContext = new AudioContext();
        const analyser = audioContext.createAnalyser();
        analyser.fftSize = 256;
        const dataArray = new Uint8Array(analyser.frequencyBinCount);
        const microphone = audioContext.createMediaStreamSource(stream);
        const gainNode = audioContext.createGain();
        
        // Connect microphone to analyser for level monitoring
        microphone.connect(analyser);
        
        // Connect microphone to speakers for playback
        microphone.connect(gainNode);
        gainNode.connect(audioContext.destination);
        gainNode.gain.value = 1.0; // Full volume playback

        micMonitorContextRef.current = audioContext;
        micMonitorStreamRef.current = stream;
        micMonitorGainRef.current = gainNode;

        const tick = () => {
          analyser.getByteFrequencyData(dataArray);
          const avg = dataArray.reduce((a, b) => a + b, 0) / dataArray.length;
          setMicLevel(Math.min(100, Math.round((avg / 255) * 100 * 3)));
          micAnimFrameRef.current = requestAnimationFrame(tick);
        };
        micAnimFrameRef.current = requestAnimationFrame(tick);

        setMicMonitoring(true);
      } catch (e) {
        console.error('Microphone monitoring failed:', e);
      }
    }
  }, [micMonitoring, settings.microphoneId, settings.noiseSuppression, settings.echoCancellation, settings.autoGainControl]);

  // Cleanup monitoring on unmount
  useEffect(() => {
    return () => {
      if (micAnimFrameRef.current !== null) {
        cancelAnimationFrame(micAnimFrameRef.current);
      }
      if (micMonitorStreamRef.current) {
        micMonitorStreamRef.current.getTracks().forEach((track) => track.stop());
      }
      if (micMonitorContextRef.current) {
        micMonitorContextRef.current.close();
      }
    };
  }, []);

  // Apply processing toggles to the live monitor track without tearing it down.
  useEffect(() => {
    if (!micMonitoring) return;
    const track = micMonitorStreamRef.current?.getAudioTracks()[0];
    if (!track) return;
    track
      .applyConstraints({
        noiseSuppression: settings.noiseSuppression,
        echoCancellation: settings.echoCancellation,
        autoGainControl: settings.autoGainControl,
        voiceIsolation: settings.noiseSuppression,
      } as MediaTrackConstraints)
      .catch((e) => console.error('Failed to apply mic processing constraints:', e));
  }, [
    micMonitoring,
    settings.noiseSuppression,
    settings.echoCancellation,
    settings.autoGainControl,
  ]);

  return (
    <Page>
      <PageHeader>
        <Box grow="Yes" gap="200">
          <Box grow="Yes" alignItems="Center" gap="200">
            <IconButton onClick={requestClose}>
              <Icon src={Icons.ArrowLeft} />
            </IconButton>
            <Text size="H4" truncate>
              Audio & Video
            </Text>
          </Box>
        </Box>
      </PageHeader>
      <Box grow="Yes">
        <Scroll hideTrack visibility="Hover">
          <PageContent>
            <Box direction="Column" gap="700">
              {permissionStatus === 'denied' && (
                <SequenceCard
                  className={SequenceCardStyle}
                  variant="SurfaceVariant"
                  direction="Column"
                  gap="400"
                >
                  <Header size="400">
                    <Box gap="200" grow="Yes">
                      <Text size="H4">Permission Required</Text>
                    </Box>
                  </Header>
                  <SettingTile
                    title="Microphone Access Denied"
                    description="Please allow microphone access in your browser settings to use audio features."
                  />
                </SequenceCard>
              )}

              <SequenceCard
                className={SequenceCardStyle}
                variant="SurfaceVariant"
                direction="Column"
                gap="400"
              >
                <Header size="400">
                  <Box gap="200" grow="Yes">
                    <Text size="H4">Microphone</Text>
                  </Box>
                </Header>
                <SettingTile
                  title="Input Device"
                  description="Select which microphone to use for voice calls."
                  after={
                    <Box alignItems="Center" gap="200">
                      <DeviceSelectButton
                        devices={microphones}
                        selectedId={settings.microphoneId}
                        onSelect={handleMicrophoneSelect}
                      />
                      <Box direction="Column" gap="100" alignItems="End">
                        <Box gap="200" alignItems="Center">
                          <Button
                            size="300"
                            variant={micTestState === 'error' ? 'Critical' : micTestState === 'done' ? 'Success' : 'Secondary'}
                            fill="Soft"
                            radii="300"
                            onClick={handleTestMicrophone}
                            disabled={micTestState === 'testing' || micMonitoring}
                          >
                            <Text size="T300">
                              {micTestState === 'testing' ? 'Testing...' : micTestState === 'done' ? 'Done ✓' : micTestState === 'error' ? 'Failed' : 'Test'}
                            </Text>
                          </Button>
                          <Button
                            size="300"
                            variant={micMonitoring ? 'Primary' : 'Secondary'}
                            fill={micMonitoring ? 'Solid' : 'Soft'}
                            radii="300"
                            onClick={handleMicMonitoringToggle}
                            disabled={micTestState === 'testing'}
                          >
                            <Text size="T300">
                              {micMonitoring ? 'Stop' : 'Monitor'}
                            </Text>
                          </Button>
                        </Box>
                        {(micTestState === 'testing' || micMonitoring) && (
                          <Box style={{ width: toRem(160), height: toRem(6), background: color.Surface.Container, borderRadius: toRem(3), overflow: 'hidden' }}>
                            <Box style={{ width: `${micLevel}%`, height: '100%', background: micMonitoring ? color.Success.Main : color.Primary.Main, transition: 'width 0.05s ease' }} />
                          </Box>
                        )}
                      </Box>
                    </Box>
                  }
                />
              </SequenceCard>

              <SequenceCard
                className={SequenceCardStyle}
                variant="SurfaceVariant"
                direction="Column"
                gap="400"
              >
                <Header size="400">
                  <Box gap="200" grow="Yes">
                    <Text size="H4">Speaker</Text>
                  </Box>
                </Header>
                <SettingTile
                  title="Output Device"
                  description="Select which speaker to use for call audio."
                  after={
                    <Box alignItems="Center" gap="200">
                      <DeviceSelectButton
                        devices={speakers}
                        selectedId={settings.speakerId}
                        onSelect={handleSpeakerSelect}
                      />
                      <Button
                        size="300"
                        variant={speakerTestState === 'error' ? 'Critical' : speakerTestState === 'done' ? 'Success' : 'Secondary'}
                        fill="Soft"
                        radii="300"
                        onClick={handleTestSpeaker}
                        disabled={speakerTestState === 'testing'}
                      >
                        <Text size="T300">
                          {speakerTestState === 'testing' ? 'Playing...' : speakerTestState === 'done' ? 'Done ✓' : speakerTestState === 'error' ? 'Failed' : 'Test'}
                        </Text>
                      </Button>
                    </Box>
                  }
                />
              </SequenceCard>

              <SequenceCard
                className={SequenceCardStyle}
                variant="SurfaceVariant"
                direction="Column"
                gap="400"
              >
                <Header size="400">
                  <Box gap="200" grow="Yes">
                    <Text size="H4">Audio Processing</Text>
                  </Box>
                </Header>
                <SettingTile
                  title="Noise Suppression"
                  description="Reduce background noise from your microphone during calls."
                  after={
                    <Switch
                      variant="Primary"
                      value={settings.noiseSuppression}
                      onChange={handleNoiseSuppressionChange}
                    />
                  }
                />
                <SettingTile
                  title="Echo Cancellation"
                  description="Prevent echo when your speakers feed back into your microphone."
                  after={
                    <Switch
                      variant="Primary"
                      value={settings.echoCancellation}
                      onChange={handleEchoCancellationChange}
                    />
                  }
                />
                <SettingTile
                  title="Auto Gain Control"
                  description="Automatically adjust microphone volume for consistent levels."
                  after={
                    <Switch
                      variant="Primary"
                      value={settings.autoGainControl}
                      onChange={handleAutoGainControlChange}
                    />
                  }
                />
              </SequenceCard>

              <SequenceCard
                className={SequenceCardStyle}
                variant="SurfaceVariant"
                direction="Column"
                gap="400"
              >
                <Header size="400">
                  <Box gap="200" grow="Yes">
                    <Text size="H4">Screen Sharing</Text>
                  </Box>
                </Header>
                <SettingTile
                  title="Resolution"
                  description="Maximum resolution when sharing your screen."
                  after={
                    <ScreenShareResolutionSelect
                      value={settings.screenShareResolution}
                      onChange={handleScreenShareResolutionChange}
                    />
                  }
                />
                <SettingTile
                  title="Bitrate"
                  description="Video quality for screen sharing. Higher uses more bandwidth."
                  after={
                    <ScreenShareBitrateSelect
                      value={settings.screenShareBitrate}
                      onChange={handleScreenShareBitrateChange}
                    />
                  }
                />
                <SettingTile
                  title="Frame Rate"
                  description="Frames per second when sharing your screen."
                  after={
                    <ScreenShareFrameRateSelect
                      value={settings.screenShareFrameRate}
                      onChange={handleScreenShareFrameRateChange}
                    />
                  }
                />
                <SettingTile
                  title="Show Remote Cursor"
                  description="Display other participants' cursors on shared screens. Both users must have this enabled."
                  after={
                    <Switch
                      variant="Primary"
                      value={showRemoteCursor}
                      onChange={setShowRemoteCursor}
                    />
                  }
                />
              </SequenceCard>

              <SequenceCard
                className={SequenceCardStyle}
                variant="SurfaceVariant"
                direction="Column"
                gap="400"
              >
                <Header size="400">
                  <Box gap="200" grow="Yes">
                    <Text size="H4">Tips</Text>
                  </Box>
                </Header>
                <Box direction="Column" gap="200" style={{ padding: `0 ${config.space.S300}` }}>
                  <Text size="T300">
                    • If you don&apos;t see your devices, make sure they are connected and permissions are granted.
                  </Text>
                  <Text size="T300">
                    • The &quot;Test&quot; button will help verify your devices are working correctly.
                  </Text>
                  <Text size="T300">
                    • Changes are saved automatically and will apply to your next call.
                  </Text>
                </Box>
              </SequenceCard>
            </Box>
          </PageContent>
        </Scroll>
      </Box>
    </Page>
  );
}
