<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { toast } from 'vue-sonner'
import { Button } from '@/components/ui/button'
import { Label } from '@/components/ui/label'
import { Separator } from '@/components/ui/separator'
import { NativeSelect, NativeSelectOption } from '@/components/ui/native-select'
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
} from '@/components/ui/select'
import { Monitor, RefreshCw, Loader2, Zap, Scale, Image } from 'lucide-vue-next'
import HelpTooltip from '@/components/HelpTooltip.vue'
import {
  configApi,
  streamApi,
  type VideoCodecInfo,
  type EncoderBackendInfo,
  type BitratePreset,
  type StreamConstraintsResponse,
} from '@/api'
import { getVideoFormatState, isVideoFormatSelectable } from '@/lib/video-format-support'
import { formatFpsLabel, toConfigFps } from '@/lib/fps'
import { formatVideoDeviceLabel } from '@/lib/video-device-label'
import { useConfigStore } from '@/stores/config'

export type VideoMode = 'mjpeg' | 'h264' | 'h265' | 'vp8' | 'vp9'

interface VideoDevice {
  path: string
  name: string
  driver: string
  formats: {
    format: string
    description: string
    resolutions: {
      width: number
      height: number
      fps: number[]
    }[]
  }[]
  has_signal?: boolean
}

const props = defineProps<{
  open: boolean
  videoMode: VideoMode
}>()

const emit = defineEmits<{
  (e: 'update:open', value: boolean): void
  (e: 'update:videoMode', value: VideoMode): void
}>()

const { t } = useI18n()
const configStore = useConfigStore()

// Device list
const devices = ref<VideoDevice[]>([])
const loadingDevices = ref(false)

const codecs = ref<VideoCodecInfo[]>([])
const loadingCodecs = ref(false)

// Backend list
const backends = ref<EncoderBackendInfo[]>([])
const constraints = ref<StreamConstraintsResponse | null>(null)
const currentEncoderBackend = computed(() => configStore.stream?.encoder || 'auto')
const isServiceActive = (status: string | undefined) => status === 'starting' || status === 'running'
const isRtspEnabled = computed(() => isServiceActive(configStore.rtspStatus?.service_status))
const isRustdeskEnabled = computed(() => isServiceActive(configStore.rustdeskStatus?.service_status))
const isRtspCodecLocked = computed(() => isRtspEnabled.value)
const isRustdeskWebrtcLocked = computed(() => !isRtspEnabled.value && isRustdeskEnabled.value)
const codecLockSources = computed(() => {
  if (isRtspCodecLocked.value) {
    return isRustdeskEnabled.value ? 'RTSP/RustDesk' : 'RTSP'
  }
  if (isRustdeskWebrtcLocked.value) return 'RustDesk'
  return ''
})
const codecLockMessage = computed(() => {
  if (!codecLockSources.value) return ''
  return t('actionbar.multiSourceCodecLocked', { sources: codecLockSources.value })
})
const videoParamWarningSources = computed(() => {
  if (isRtspEnabled.value && isRustdeskEnabled.value) return 'RTSP/RustDesk'
  if (isRtspEnabled.value) return 'RTSP'
  if (isRustdeskEnabled.value) return 'RustDesk'
  return ''
})
const videoParamWarningMessage = computed(() => {
  if (!videoParamWarningSources.value) return ''
  return t('actionbar.multiSourceVideoParamsWarning', { sources: videoParamWarningSources.value })
})
const isCodecLocked = computed(() => !!codecLockMessage.value)

const isCodecOptionDisabled = (codecId: string): boolean => {
  if (!isBrowserSupported(codecId)) return true
  if (isRustdeskWebrtcLocked.value && codecId === 'mjpeg') return true
  return false
}

// Browser supported codecs (WebRTC receive capabilities)
const browserSupportedCodecs = ref<Set<string>>(new Set())

// Check browser WebRTC codec support
function detectBrowserCodecSupport() {
  const supported = new Set<string>()

  // MJPEG is always supported (HTTP streaming, no WebRTC)
  supported.add('mjpeg')

  // Check WebRTC receive capabilities
  if (typeof RTCRtpReceiver !== 'undefined' && RTCRtpReceiver.getCapabilities) {
    const capabilities = RTCRtpReceiver.getCapabilities('video')
    if (capabilities?.codecs) {
      for (const codec of capabilities.codecs) {
        const mimeType = codec.mimeType.toLowerCase()
        if (mimeType.includes('h264') || mimeType.includes('avc')) {
          supported.add('h264')
        }
        if (mimeType.includes('h265') || mimeType.includes('hevc')) {
          supported.add('h265')
        }
        if (mimeType.includes('vp8')) {
          supported.add('vp8')
        }
        if (mimeType.includes('vp9')) {
          supported.add('vp9')
        }
        if (mimeType.includes('av1')) {
          supported.add('av1')
        }
      }
    }
  } else {
    supported.add('h264')
    supported.add('vp8')
    supported.add('vp9')
  }

  browserSupportedCodecs.value = supported
  console.info('[VideoConfig] Browser supported codecs:', Array.from(supported))
}

// Check if a codec is supported by browser
const isBrowserSupported = (codecId: string): boolean => {
  if (codecId === 'mjpeg') return true
  return browserSupportedCodecs.value.has(codecId)
}

const getFormatState = (formatName: string) =>
  getVideoFormatState(formatName, props.videoMode, currentEncoderBackend.value)

const isFormatUnsupported = (formatName: string): boolean =>
  getFormatState(formatName) === 'unsupported'

// Translate backend name for display
const translateBackendName = (backend: string | undefined): string => {
  if (!backend) return ''
  // Translate known backend names
  const lowerBackend = backend.toLowerCase()
  if (lowerBackend === 'software') {
    return t('actionbar.backendSoftware')
  }
  if (lowerBackend === 'auto') {
    return t('actionbar.backendAuto')
  }
  // Hardware backends (VAAPI, V4L2 M2M, etc.) keep original names
  return backend
}

const hasHighFps = (format: { resolutions: { fps: number[] }[] }): boolean => {
  return format.resolutions.some(res => res.fps.some(fps => fps >= 30))
}

const isFormatRecommended = (formatName: string): boolean => {
  if (!isVideoFormatSelectable(formatName, props.videoMode, currentEncoderBackend.value)) {
    return false
  }

  const formats = availableFormats.value
  const upperFormat = formatName.toUpperCase()

  // MJPEG/HTTP mode: recommend MJPEG
  if (props.videoMode === 'mjpeg') {
    return upperFormat === 'MJPEG'
  }

  // WebRTC mode: check NV12 first, then YUYV
  const currentFormat = formats.find(f => f.format.toUpperCase() === upperFormat)
  if (!currentFormat) return false

  const nv12Format = formats.find(f => f.format.toUpperCase() === 'NV12')
  const nv12HasHighFps = nv12Format && hasHighFps(nv12Format)

  const yuyvFormat = formats.find(f => f.format.toUpperCase() === 'YUYV')
  const yuyvHasHighFps = yuyvFormat && hasHighFps(yuyvFormat)

  if (nv12HasHighFps) {
    return upperFormat === 'NV12'
  }

  if (yuyvHasHighFps) {
    return upperFormat === 'YUYV'
  }

  return false
}

// In WebRTC mode, compressed formats (MJPEG/JPEG) are not recommended
const isFormatNotRecommended = (formatName: string): boolean => {
  return getFormatState(formatName) === 'not_recommended'
}

const selectedDevice = ref<string>('')
const selectedFormat = ref<string>('')
const selectedResolution = ref<string>('')
const selectedFps = ref<number>(30)
const selectedBitratePreset = ref<'Speed' | 'Balanced' | 'Quality'>('Balanced')
const isDirty = ref(false)

const selectedFormatStatus = computed<'recommended' | 'not_recommended' | 'unsupported' | null>(() => {
  if (!selectedFormat.value) return null
  if (isFormatUnsupported(selectedFormat.value)) return 'unsupported'
  if (isFormatRecommended(selectedFormat.value)) return 'recommended'
  if (isFormatNotRecommended(selectedFormat.value)) return 'not_recommended'
  return null
})

const applying = ref(false)
const applyingBitrate = ref(false)

const currentConfig = computed(() => ({
  device: configStore.video?.device || '',
  format: configStore.video?.format || '',
  width: configStore.video?.width || 1920,
  height: configStore.video?.height || 1080,
  fps: configStore.video?.fps || 30,
}))

const buttonText = computed(() => t('actionbar.videoConfig'))

// Available codecs for selection (filtered by backend support and enriched with backend info)
const availableCodecs = computed(() => {
  const allAvailable = codecs.value.filter(c => c.available)

  // Auto mode: show all available with their best (hardware-preferred) backend
  if (currentEncoderBackend.value === 'auto') {
    return allAvailable
  }

  // Specific backend: filter by supported formats and override backend info
  const backend = backends.value.find(b => b.id === currentEncoderBackend.value)
  if (!backend) return allAvailable

  const backendFiltered = allAvailable
    .filter(codec => {
      // MJPEG is always available (doesn't require encoder)
      if (codec.id === 'mjpeg') return true
      // Check if codec format is supported by the configured backend
      return backend.supported_formats.includes(codec.id)
    })
    .map(codec => {
      // For MJPEG, keep original info
      if (codec.id === 'mjpeg') return codec

      // Override backend info for WebRTC codecs based on selected backend
      return {
        ...codec,
        hardware: backend.is_hardware,
        backend: backend.name,
      }
    })

  const allowed = constraints.value?.allowed_codecs
  if (!allowed || allowed.length === 0) {
    return backendFiltered
  }

  return backendFiltered.filter(codec => allowed.includes(codec.id))
})

const availableFormats = computed(() => {
  const device = devices.value.find(d => d.path === selectedDevice.value)
  return device?.formats || []
})

const availableFormatOptions = computed(() => {
  return availableFormats.value.map(format => ({
    ...format,
    state: getFormatState(format.format),
    disabled: isFormatUnsupported(format.format),
  }))
})

const availableResolutions = computed(() => {
  const format = availableFormats.value.find(f => f.format === selectedFormat.value)
  return format?.resolutions || []
})

const availableFps = computed(() => {
  const resolution = availableResolutions.value.find(
    r => `${r.width}x${r.height}` === selectedResolution.value
  )
  return resolution?.fps || []
})

const selectedFormatInfo = computed(() =>
  availableFormatOptions.value.find(format => format.format === selectedFormat.value) ?? null
)

const selectedCodecInfo = computed(() => {
  const codec = availableCodecs.value.find(c => c.id === props.videoMode)
  return codec || null
})

// Load devices
async function loadDevices() {
  loadingDevices.value = true
  try {
    const result = await configApi.listDevices()
    devices.value = result.video
  } catch (e) {
    console.info('[VideoConfig] Failed to load devices')
    toast.error(t('config.loadDevicesFailed'))
  } finally {
    loadingDevices.value = false
  }
}

// Load available codecs and backends
async function loadCodecs() {
  loadingCodecs.value = true
  try {
    const result = await streamApi.getCodecs()
    codecs.value = result.codecs
    backends.value = result.backends || []
  } catch (e) {
    console.info('[VideoConfig] Failed to load codecs')
    codecs.value = [
      { id: 'mjpeg', name: 'MJPEG / HTTP', protocol: 'http', hardware: false, backend: 'software', available: true },
      { id: 'h264', name: 'H.264 / WebRTC', protocol: 'webrtc', hardware: false, backend: 'software', available: true },
    ]
  } finally {
    loadingCodecs.value = false
  }
}

async function loadConstraints() {
  try {
    constraints.value = await streamApi.getConstraints()
  } catch {
    constraints.value = null
  }
}

function initializeFromCurrent() {
  const config = currentConfig.value
  selectedDevice.value = config.device
  selectedFormat.value = config.format
  selectedResolution.value = `${config.width}x${config.height}`
  selectedFps.value = config.fps
  isDirty.value = false
}

function syncFromCurrentIfChanged() {
  const config = currentConfig.value
  const nextResolution = `${config.width}x${config.height}`

  if (selectedDevice.value === config.device
      && selectedFormat.value === config.format
      && selectedResolution.value === nextResolution
      && selectedFps.value === config.fps) {
    return
  }

  selectedDevice.value = config.device
  selectedFormat.value = config.format
  selectedResolution.value = nextResolution
  selectedFps.value = config.fps
  isDirty.value = false
}

function handleVideoModeChange(mode: unknown) {
  if (typeof mode !== 'string') return

  if (isRtspCodecLocked.value) {
    toast.warning(codecLockMessage.value)
    return
  }

  if (isRustdeskWebrtcLocked.value && mode === 'mjpeg') {
    toast.warning(codecLockMessage.value)
    return
  }

  if (constraints.value?.allowed_codecs?.length && !constraints.value.allowed_codecs.includes(mode)) {
    toast.error(constraints.value.reason || t('actionbar.selectMode'))
    return
  }

  emit('update:videoMode', mode as VideoMode)
}

function findFirstSelectableFormat(
  formats: VideoDevice['formats'],
): VideoDevice['formats'][number] | undefined {
  return formats.find(format =>
    isVideoFormatSelectable(format.format, props.videoMode, currentEncoderBackend.value),
  )
}

function clearFormatSelection() {
  selectedFormat.value = ''
  selectedResolution.value = ''
  selectedFps.value = 30
}

function selectFormatWithDefaults(format: string) {
  if (isFormatUnsupported(format)) return

  selectedFormat.value = format

  const formatData = availableFormats.value.find(f => f.format === format)
  const resolution = formatData?.resolutions[0]
  if (!resolution) {
    selectedResolution.value = ''
    selectedFps.value = 30
    return
  }

  selectedResolution.value = `${resolution.width}x${resolution.height}`
  selectedFps.value = resolution.fps[0] || 30
}

// Handle device change
function handleDeviceChange(devicePath: unknown) {
  if (typeof devicePath !== 'string') return
  selectedDevice.value = devicePath
  isDirty.value = true

  const device = devices.value.find(d => d.path === devicePath)
  const format = device ? findFirstSelectableFormat(device.formats) : undefined
  if (!format) {
    clearFormatSelection()
    return
  }

  selectFormatWithDefaults(format.format)
}

function handleFormatChange(format: unknown) {
  if (typeof format !== 'string') return
  if (isFormatUnsupported(format)) return

  selectFormatWithDefaults(format)
  isDirty.value = true
}

function handleResolutionChange(resolution: unknown) {
  if (typeof resolution !== 'string') return
  selectedResolution.value = resolution
  isDirty.value = true

  const resolutionData = availableResolutions.value.find(
    r => `${r.width}x${r.height}` === resolution
  )
  if (resolutionData?.fps[0]) {
    selectedFps.value = resolutionData.fps[0]
  }
}

function handleFpsChange(fps: unknown) {
  if (typeof fps !== 'string' && typeof fps !== 'number') return
  selectedFps.value = typeof fps === 'string' ? Number(fps) : fps
  isDirty.value = true
}

async function applyBitratePreset(preset: 'Speed' | 'Balanced' | 'Quality') {
  if (applyingBitrate.value) return
  applyingBitrate.value = true
  try {
    const bitratePreset: BitratePreset = { type: preset }
    await streamApi.setBitratePreset(bitratePreset)
  } catch (e) {
    console.info('[VideoConfig] Failed to apply bitrate preset:', e)
  } finally {
    applyingBitrate.value = false
  }
}

function handleBitratePresetChange(preset: 'Speed' | 'Balanced' | 'Quality') {
  selectedBitratePreset.value = preset
  if (props.videoMode !== 'mjpeg') {
    applyBitratePreset(preset)
  }
}

async function applyVideoConfig() {
  const [width, height] = selectedResolution.value.split('x').map(Number)

  applying.value = true
  try {
    await configStore.updateVideo({
      device: selectedDevice.value,
      format: selectedFormat.value,
      width,
      height,
      fps: toConfigFps(selectedFps.value),
    })

    isDirty.value = false
    // Stream state will be updated via WebSocket system.device_info event
  } catch (e) {
    console.info('[VideoConfig] Failed to apply config:', e)
  } finally {
    applying.value = false
  }
}

watch(() => props.open, (isOpen) => {
  if (!isOpen) {
    isDirty.value = false
    return
  }

  // Detect browser codec support on first open
  if (browserSupportedCodecs.value.size === 0) {
    detectBrowserCodecSupport()
  }
  // Load devices on first open
  if (devices.value.length === 0) {
    loadDevices()
  }
  // Load codecs and backends on first open
  if (codecs.value.length === 0) {
    loadCodecs()
  }

  loadConstraints()

  Promise.all([
    configStore.refreshVideo(),
    configStore.refreshStream(),
    configStore.refreshRtspStatus(),
    configStore.refreshRustdeskStatus(),
  ]).then(() => {
    initializeFromCurrent()
  }).catch(() => {
    initializeFromCurrent()
  })
})

// Sync selected values when backend config changes (e.g., auto format switch on mode change)
watch(currentConfig, () => {
  if (applying.value) return
  if (props.open && isDirty.value) return
  syncFromCurrentIfChanged()
}, { deep: true })

watch(
  [availableFormatOptions, () => props.videoMode, currentEncoderBackend],
  () => {
    if (!selectedDevice.value) return

    const currentFormat = availableFormatOptions.value.find(
      format => format.format === selectedFormat.value,
    )
    if (currentFormat && !currentFormat.disabled) {
      return
    }

    const fallback = availableFormatOptions.value.find(format => !format.disabled)
    if (!fallback) {
      clearFormatSelection()
      return
    }

    selectFormatWithDefaults(fallback.format)
  },
  { deep: true },
)
</script>

<template>
  <Popover :open="open" @update:open="emit('update:open', $event)">
    <PopoverTrigger as-child>
      <Button variant="ghost" size="sm" class="h-7 w-7 sm:h-8 sm:w-auto p-0 sm:px-2 sm:gap-1.5 text-xs">
        <Monitor class="h-3.5 w-3.5 sm:h-4 sm:w-4" />
        <span class="hidden sm:inline">{{ buttonText }}</span>
      </Button>
    </PopoverTrigger>
    <PopoverContent class="w-[min(320px,92vw)] p-3" align="start">
      <div class="space-y-3">
        <h4 class="text-sm font-medium">{{ t('actionbar.videoConfig') }}</h4>

        <Separator />

        <!-- Stream Settings Section -->
        <div class="space-y-3">
          <h5 class="text-xs font-medium text-muted-foreground">{{ t('actionbar.streamSettings') }}</h5>

          <!-- Mode Selection -->
          <div class="space-y-2">
            <div class="flex items-center gap-1">
              <Label class="text-xs">{{ t('actionbar.videoMode') }}</Label>
              <HelpTooltip :content="t('actionbar.videoModeHint')" icon-size="sm" side="right" />
            </div>
            <Select
              :model-value="props.videoMode"
              @update:model-value="handleVideoModeChange"
              :disabled="loadingCodecs || availableCodecs.length === 0 || isRtspCodecLocked"
            >
              <SelectTrigger class="h-8 w-full text-xs">
                <div v-if="selectedCodecInfo" class="flex items-center gap-1.5 truncate">
                  <span class="truncate">{{ selectedCodecInfo.name }}</span>
                  <span
                    v-if="selectedCodecInfo.backend && selectedCodecInfo.id !== 'mjpeg'"
                    class="text-[10px] px-1 py-0.5 rounded shrink-0"
                    :class="selectedCodecInfo.hardware
                      ? 'bg-info/10 text-info'
                      : 'bg-warning/10 text-warning'"
                  >
                    {{ translateBackendName(selectedCodecInfo.backend) }}
                  </span>
                </div>
                <span v-else class="text-muted-foreground">{{ loadingCodecs ? t('common.loading') : t('actionbar.selectMode') }}</span>
              </SelectTrigger>
              <SelectContent>
                <SelectItem
                  v-for="codec in availableCodecs"
                  :key="codec.id"
                  :value="codec.id"
                  :disabled="isCodecOptionDisabled(codec.id)"
                  :class="['text-xs', { 'opacity-50': isCodecOptionDisabled(codec.id) }]"
                >
                  <div class="flex items-center gap-2">
                    <span>{{ codec.name }}</span>
                    <!-- Show backend badge for WebRTC codecs -->
                    <span
                      v-if="codec.backend && codec.id !== 'mjpeg'"
                      class="text-[10px] px-1.5 py-0.5 rounded"
                      :class="codec.hardware
                        ? 'bg-info/10 text-info'
                        : 'bg-warning/10 text-warning'"
                    >
                      {{ translateBackendName(codec.backend) }}
                    </span>
                    <span
                      v-if="!isBrowserSupported(codec.id)"
                      class="text-[10px] text-muted-foreground"
                    >
                      ({{ t('actionbar.browserUnsupported') }})
                    </span>
                  </div>
                </SelectItem>
              </SelectContent>
            </Select>
            <p v-if="isCodecLocked" class="text-xs text-warning">
              {{ codecLockMessage }}
            </p>
          </div>

          <!-- Bitrate Preset - Only shown for WebRTC modes -->
          <div v-if="props.videoMode !== 'mjpeg'" class="space-y-2">
            <div class="flex items-center gap-1">
              <Label class="text-xs">{{ t('actionbar.bitratePreset') }}</Label>
              <HelpTooltip :content="t('help.videoBitratePreset')" icon-size="sm" />
            </div>
            <div class="grid grid-cols-3 gap-1.5">
              <Button
                variant="outline"
                size="sm"
                :class="[
                  'h-auto py-1.5 px-2 flex flex-col items-center gap-0.5',
                  selectedBitratePreset === 'Speed' && 'border-primary bg-primary/10'
                ]"
                :disabled="applyingBitrate"
                @click="handleBitratePresetChange('Speed')"
              >
                <Zap class="h-3.5 w-3.5" />
                <span class="text-[10px] font-medium">{{ t('actionbar.bitrateSpeed') }}</span>
              </Button>
              <Button
                variant="outline"
                size="sm"
                :class="[
                  'h-auto py-1.5 px-2 flex flex-col items-center gap-0.5',
                  selectedBitratePreset === 'Balanced' && 'border-primary bg-primary/10'
                ]"
                :disabled="applyingBitrate"
                @click="handleBitratePresetChange('Balanced')"
              >
                <Scale class="h-3.5 w-3.5" />
                <span class="text-[10px] font-medium">{{ t('actionbar.bitrateBalanced') }}</span>
              </Button>
              <Button
                variant="outline"
                size="sm"
                :class="[
                  'h-auto py-1.5 px-2 flex flex-col items-center gap-0.5',
                  selectedBitratePreset === 'Quality' && 'border-primary bg-primary/10'
                ]"
                :disabled="applyingBitrate"
                @click="handleBitratePresetChange('Quality')"
              >
                <Image class="h-3.5 w-3.5" />
                <span class="text-[10px] font-medium">{{ t('actionbar.bitrateQuality') }}</span>
              </Button>
            </div>
          </div>

        </div>

        <!-- Device Settings Section -->
        <Separator />

        <div class="space-y-3">
          <p v-if="videoParamWarningMessage" class="text-xs text-warning">
            {{ videoParamWarningMessage }}
          </p>

          <div class="flex items-center justify-between">
            <h5 class="text-xs font-medium text-muted-foreground">{{ t('actionbar.deviceSettings') }}</h5>
            <Button
              variant="ghost"
              size="icon"
              class="h-6 w-6"
              :disabled="loadingDevices"
              @click="loadDevices"
            >
              <RefreshCw :class="['h-3.5 w-3.5', loadingDevices && 'animate-spin']" />
            </Button>
          </div>

          <!-- Device Selection -->
          <div class="space-y-2">
            <Label class="text-xs">{{ t('actionbar.videoDevice') }}</Label>
            <NativeSelect
              :model-value="selectedDevice"
              @update:model-value="handleDeviceChange"
              :disabled="loadingDevices || devices.length === 0"
              class="h-8 w-full text-xs"
            >
                <NativeSelectOption value="">{{ loadingDevices ? t('common.loading') : t('actionbar.selectDevice') }}</NativeSelectOption>
                <NativeSelectOption
                  v-for="device in devices"
                  :key="device.path"
                  :value="device.path"
                  class="text-xs"
                >
                  {{ formatVideoDeviceLabel(device) }}
                </NativeSelectOption>
            </NativeSelect>
          </div>

          <!-- Format Selection -->
          <div class="space-y-2">
            <Label class="text-xs">{{ t('actionbar.videoFormat') }}</Label>
            <Select
              :model-value="selectedFormat"
              @update:model-value="handleFormatChange"
              :disabled="!selectedDevice || availableFormats.length === 0"
            >
              <SelectTrigger class="h-8 w-full text-xs">
                <div v-if="selectedFormatInfo" class="flex min-w-0 items-center gap-1.5">
                  <span class="truncate">{{ selectedFormatInfo.description }}</span>
                  <span
                    v-if="selectedFormatStatus === 'recommended'"
                    class="shrink-0 rounded bg-info/10 px-1 py-0.5 text-[10px] text-info"
                  >
                    {{ t('actionbar.recommended') }}
                  </span>
                  <span
                    v-else-if="selectedFormatStatus === 'not_recommended'"
                    class="shrink-0 rounded bg-warning/10 px-1 py-0.5 text-[10px] text-warning"
                  >
                    {{ t('actionbar.notRecommended') }}
                  </span>
                  <span
                    v-else-if="selectedFormatStatus === 'unsupported'"
                    class="shrink-0 rounded bg-muted px-1 py-0.5 text-[10px] text-muted-foreground"
                  >
                    {{ t('common.notSupportedYet') }}
                  </span>
                </div>
                <span v-else class="text-muted-foreground">{{ t('actionbar.selectFormat') }}</span>
              </SelectTrigger>
              <SelectContent>
                <SelectItem
                  v-for="format in availableFormatOptions"
                  :key="format.format"
                  :value="format.format"
                  :disabled="format.disabled"
                  class="text-xs"
                >
                  <div class="flex items-center gap-2">
                    <span>{{ format.description }}</span>
                    <span
                      v-if="isFormatRecommended(format.format)"
                      class="rounded bg-info/10 px-1.5 py-0.5 text-[10px] text-info"
                    >
                      {{ t('actionbar.recommended') }}
                    </span>
                    <span
                      v-else-if="isFormatNotRecommended(format.format)"
                      class="rounded bg-warning/10 px-1.5 py-0.5 text-[10px] text-warning"
                    >
                      {{ t('actionbar.notRecommended') }}
                    </span>
                  </div>
                </SelectItem>
              </SelectContent>
            </Select>
          </div>

          <!-- Resolution Selection -->
          <div class="space-y-2">
            <Label class="text-xs">{{ t('actionbar.videoResolution') }}</Label>
            <NativeSelect
              :model-value="selectedResolution"
              @update:model-value="handleResolutionChange"
              :disabled="!selectedFormat || availableResolutions.length === 0"
              class="h-8 w-full text-xs"
            >
                <NativeSelectOption value="">{{ t('actionbar.selectResolution') }}</NativeSelectOption>
                <NativeSelectOption
                  v-for="res in availableResolutions"
                  :key="`${res.width}x${res.height}`"
                  :value="`${res.width}x${res.height}`"
                  class="text-xs"
                >
                  {{ res.width }} x {{ res.height }}
                </NativeSelectOption>
            </NativeSelect>
          </div>

          <!-- FPS Selection -->
          <div class="space-y-2">
            <Label class="text-xs">{{ t('actionbar.videoFps') }}</Label>
            <NativeSelect
              :model-value="String(selectedFps)"
              @update:model-value="handleFpsChange"
              :disabled="!selectedResolution || availableFps.length === 0"
              class="h-8 w-full text-xs"
            >
                <NativeSelectOption value="">{{ t('actionbar.selectFps') }}</NativeSelectOption>
                <NativeSelectOption
                  v-for="fps in availableFps"
                  :key="fps"
                  :value="String(fps)"
                  class="text-xs"
                >
                  {{ formatFpsLabel(fps) }}
                </NativeSelectOption>
            </NativeSelect>
          </div>

          <!-- Apply Button -->
          <Button
            class="w-full h-8 text-xs"
            :disabled="applying || !selectedDevice || !selectedFormat"
            @click="applyVideoConfig"
          >
            <Loader2 v-if="applying" class="h-3.5 w-3.5 mr-1.5 animate-spin" />
            <span>{{ applying ? t('actionbar.applying') : t('common.apply') }}</span>
          </Button>
          </div>
      </div>
    </PopoverContent>
  </Popover>
</template>
