import { useCallback, useEffect, useMemo, useRef, useState, type ElementType, type ReactNode } from "react"
import { Control, ControlGroup, ControlLabel } from "@renderer/components/ui/control"
import { Input } from "@renderer/components/ui/input"
import { Textarea } from "@renderer/components/ui/textarea"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@renderer/components/ui/select"
import { Switch } from "@renderer/components/ui/switch"
import { useConfigQuery, useSaveConfigMutation } from "@renderer/lib/query-client"
import { ModelPresetManager } from "@renderer/components/model-preset-manager"
import { ModelSelector, ProviderModelSelector } from "@renderer/components/model-selector"
import { PresetModelSelector } from "@renderer/components/preset-model-selector"
import { Config, ModelPreset } from "@shared/types"
import {
  STT_PROVIDERS,
  CHAT_PROVIDERS,
  TTS_PROVIDERS,
  STT_PROVIDER_ID,
  CHAT_PROVIDER_ID,
  TTS_PROVIDER_ID,
  OPENAI_TTS_MODELS,
  OPENAI_TTS_VOICES,
  GROQ_TTS_MODELS,
  GROQ_TTS_VOICES_ARABIC,
  GROQ_TTS_VOICES_ENGLISH,
  GEMINI_TTS_MODELS,
  GEMINI_TTS_VOICES,
  EDGE_TTS_MODELS,
  EDGE_TTS_VOICES,
  KITTEN_TTS_VOICES,
  SUPERTONIC_TTS_LANGUAGES,
  SUPERTONIC_TTS_VOICES,
  DEFAULT_MODEL_PRESET_ID,
  getBuiltInModelPresets,
} from "@dotagents/shared"
import { getDefaultSttModel } from "@dotagents/shared/stt-models"
import { Mic, FileText, Volume2, Bot } from "lucide-react"

const SETTINGS_TEXT_SAVE_DEBOUNCE_MS = 400

function RoleProviderSelector({
  label,
  tooltip,
  value,
  onChange,
  providers,
  icon: Icon,
}: {
  label: ReactNode
  tooltip: string
  value: string
  onChange: (value: string) => void
  providers: readonly { label: string; value: string }[]
  icon: ElementType
}) {
  return (
    <Control
      label={<ControlLabel label={<span className="flex items-center gap-2"><Icon className="h-4 w-4 text-muted-foreground" />{label}</span>} tooltip={tooltip} />}
      className="px-3"
    >
      <Select value={value} onValueChange={onChange}>
        <SelectTrigger className="w-full sm:w-[220px]">
          <SelectValue />
        </SelectTrigger>
        <SelectContent>
          {providers.map((provider) => (
            <SelectItem key={provider.value} value={provider.value}>
              {provider.label}
            </SelectItem>
          ))}
        </SelectContent>
      </Select>
    </Control>
  )
}

export function Component() {
  const configQuery = useConfigQuery()
  const saveConfigMutation = useSaveConfigMutation()
  const transcriptProcessingPromptSaveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
  const [transcriptProcessingPromptDraft, setTranscriptProcessingPromptDraft] = useState("")

  const saveConfig = useCallback((updates: Partial<Config>) => {
    if (!configQuery.data) return
    saveConfigMutation.mutate({ config: { ...configQuery.data, ...updates } })
  }, [configQuery.data, saveConfigMutation])

  const flushTranscriptProcessingPromptSave = useCallback((value: string) => {
    if (transcriptProcessingPromptSaveTimeoutRef.current) {
      clearTimeout(transcriptProcessingPromptSaveTimeoutRef.current)
      transcriptProcessingPromptSaveTimeoutRef.current = null
    }
    saveConfig({ transcriptPostProcessingPrompt: value })
  }, [saveConfig])

  const updateTranscriptProcessingPromptDraft = useCallback((value: string) => {
    setTranscriptProcessingPromptDraft(value)
    if (transcriptProcessingPromptSaveTimeoutRef.current) {
      clearTimeout(transcriptProcessingPromptSaveTimeoutRef.current)
    }
    transcriptProcessingPromptSaveTimeoutRef.current = setTimeout(() => {
      transcriptProcessingPromptSaveTimeoutRef.current = null
      saveConfig({ transcriptPostProcessingPrompt: value })
    }, SETTINGS_TEXT_SAVE_DEBOUNCE_MS)
  }, [saveConfig])

  useEffect(() => {
    setTranscriptProcessingPromptDraft(configQuery.data?.transcriptPostProcessingPrompt ?? "")
  }, [configQuery.data?.transcriptPostProcessingPrompt])

  useEffect(() => {
    return () => {
      if (transcriptProcessingPromptSaveTimeoutRef.current) {
        clearTimeout(transcriptProcessingPromptSaveTimeoutRef.current)
      }
    }
  }, [])

  const allPresets = useMemo(() => {
    const builtIn = getBuiltInModelPresets()
    const custom = configQuery.data?.modelPresets || []
    const mergedBuiltIn = builtIn.map((preset) => {
      const saved = custom.find((candidate) => candidate.id === preset.id)
      if (saved) {
        const merged = { ...preset, ...saved }
        if (preset.id === DEFAULT_MODEL_PRESET_ID && !merged.apiKey && configQuery.data?.openaiApiKey) {
          merged.apiKey = configQuery.data.openaiApiKey
        }
        return merged
      }
      if (preset.id === DEFAULT_MODEL_PRESET_ID && configQuery.data?.openaiApiKey) {
        return { ...preset, apiKey: configQuery.data.openaiApiKey }
      }
      return preset
    })

    return [...mergedBuiltIn, ...custom.filter((preset) => !preset.isBuiltIn)]
  }, [configQuery.data?.modelPresets, configQuery.data?.openaiApiKey])

  const getPresetById = useCallback((presetId?: string): ModelPreset | undefined => {
    if (!presetId) return undefined
    return allPresets.find((preset) => preset.id === presetId)
  }, [allPresets])

  if (!configQuery.data) return null

  const config = configQuery.data
  const sttProviderId = config.sttProviderId || "openai"
  const transcriptProcessingProviderId = config.transcriptPostProcessingProviderId || "openai"
  const ttsProviderId = config.ttsProviderId || "openai"
  const agentProviderId = config.agentProviderId || config.mcpToolsProviderId || "openai"
  const transcriptProcessingEnabled = config.transcriptPostProcessingEnabled ?? false
  const usesOpenAiCompatiblePreset =
    agentProviderId === "openai" ||
    (transcriptProcessingEnabled && transcriptProcessingProviderId === "openai")
  const transcriptProcessingModel = transcriptProcessingProviderId === "openai"
    ? config.transcriptPostProcessingOpenaiModel
    : transcriptProcessingProviderId === "groq"
      ? config.transcriptPostProcessingGroqModel
      : transcriptProcessingProviderId === "gemini"
        ? config.transcriptPostProcessingGeminiModel
        : config.transcriptPostProcessingChatgptWebModel

  return (
    <div className="mx-auto max-w-4xl px-6 pb-10 pt-8">
      <div className="space-y-6">
        <div className="rounded-lg border bg-muted/20 px-4 py-3">
          <h2 className="text-sm font-semibold">Model Selection</h2>
          <p className="mt-1 text-sm text-muted-foreground">
            Choose which provider powers each job, then pick the model or voice for that job here. API keys, base URLs,
            and local engine downloads live on the Providers page.
          </p>
        </div>

        <ControlGroup title="Agent Models">
          <div className="mx-3 my-2 rounded-md border border-muted bg-muted/30 px-3 py-2 text-xs text-muted-foreground">
            Choose which model powers the main agent. OpenAI-compatible presets can carry both an agent model and a transcript processing model.
          </div>

          {usesOpenAiCompatiblePreset && (
            <div className="px-3 py-2 border-b">
              <div className="pb-3">
                <span className="text-sm font-medium">OpenAI-Compatible Preset</span>
                <p className="text-xs text-muted-foreground">
                  Use this when Agent or Transcript Processing is set to OpenAI-compatible.
                </p>
              </div>
              <ModelPresetManager
                showAgentModel={agentProviderId === "openai"}
                showTranscriptCleanupModel={transcriptProcessingEnabled && transcriptProcessingProviderId === "openai"}
              />
            </div>
          )}

          {(agentProviderId === "groq" || agentProviderId === "gemini" || agentProviderId === "chatgpt-web") && (
            <div className="px-3 py-2">
              <ProviderModelSelector
                providerId={agentProviderId}
                mcpModel={
                  agentProviderId === "groq"
                    ? config.agentGroqModel || config.mcpToolsGroqModel
                    : agentProviderId === "gemini"
                      ? config.agentGeminiModel || config.mcpToolsGeminiModel
                      : config.agentChatgptWebModel || config.mcpToolsChatgptWebModel
                }
                onMcpModelChange={(value) =>
                  saveConfig(
                    agentProviderId === "groq"
                      ? { agentGroqModel: value }
                      : agentProviderId === "gemini"
                        ? { agentGeminiModel: value }
                        : { agentChatgptWebModel: value },
                  )
                }
                showMcpModel={true}
                showTranscriptModel={false}
              />
            </div>
          )}

          {agentProviderId === "chatgpt-web" && (
            <div className="border-t px-3 py-2">
              <div className="pb-2">
                <span className="text-sm font-medium">Codex options</span>
                <p className="text-xs text-muted-foreground">
                  Tune how the Codex (ChatGPT Web) model thinks and how verbose its replies are.
                </p>
              </div>
              <Control
                label={<ControlLabel label="Thinking level" tooltip="Reasoning effort sent to Codex reasoning models. Defaults to Low when unset. 'None' lets the provider answer with no extra reasoning." />}
              >
                <Select
                  value={config.openaiReasoningEffort || "low"}
                  onValueChange={(value) =>
                    saveConfig({
                      openaiReasoningEffort: value as Config["openaiReasoningEffort"],
                    })
                  }
                >
                  <SelectTrigger className="w-full sm:w-[220px]">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="none">None</SelectItem>
                    <SelectItem value="minimal">Minimal</SelectItem>
                    <SelectItem value="low">Low (default)</SelectItem>
                    <SelectItem value="medium">Medium</SelectItem>
                    <SelectItem value="high">High</SelectItem>
                    <SelectItem value="xhigh">Extra high</SelectItem>
                  </SelectContent>
                </Select>
              </Control>
              <Control
                label={<ControlLabel label="Verbosity" tooltip="Output verbosity passed as text.verbosity in the Codex responses payload." />}
              >
                <Select
                  value={config.codexTextVerbosity || "medium"}
                  onValueChange={(value) =>
                    saveConfig({
                      codexTextVerbosity: value as Config["codexTextVerbosity"],
                    })
                  }
                >
                  <SelectTrigger className="w-full sm:w-[220px]">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="low">Low</SelectItem>
                    <SelectItem value="medium">Medium (default)</SelectItem>
                    <SelectItem value="high">High</SelectItem>
                  </SelectContent>
                </Select>
              </Control>
            </div>
          )}

          {!usesOpenAiCompatiblePreset && agentProviderId === "openai" && (
            <p className="px-3 py-2 text-sm text-muted-foreground">
              OpenAI-compatible preset controls appear here when Agent or Transcript Processing uses that provider.
            </p>
          )}
        </ControlGroup>


        <ControlGroup title="Choose a Provider for Each Job" collapsible>
          <RoleProviderSelector
            label="Speech-to-Text"
            tooltip="Choose which provider listens to your audio and turns it into text."
            value={sttProviderId}
            onChange={(value) => saveConfig({ sttProviderId: value as STT_PROVIDER_ID })}
            providers={STT_PROVIDERS}
            icon={Mic}
          />

          <RoleProviderSelector
            label="Text-to-Speech"
            tooltip="Choose which provider turns text back into audio."
            value={ttsProviderId}
            onChange={(value) => saveConfig({ ttsProviderId: value as TTS_PROVIDER_ID })}
            providers={TTS_PROVIDERS}
            icon={Volume2}
          />

          <RoleProviderSelector
            label="Agent"
            tooltip="Choose which provider powers the main agent model for reasoning, skills, and tools."
            value={agentProviderId}
            onChange={(value) => saveConfig({ agentProviderId: value as CHAT_PROVIDER_ID })}
            providers={CHAT_PROVIDERS}
            icon={Bot}
          />
        </ControlGroup>

        <ControlGroup title="Transcript Processing" collapsible>
          <Control
            label={<ControlLabel label="Enabled" tooltip="Optionally clean up punctuation, formatting, or wording after transcription and before the transcript is used elsewhere." />}
            className="px-3"
          >
            <Switch
              checked={transcriptProcessingEnabled}
              onCheckedChange={(checked) => saveConfig({ transcriptPostProcessingEnabled: checked })}
            />
          </Control>

          {transcriptProcessingEnabled && (
            <>
              <RoleProviderSelector
                label="Provider"
                tooltip="Choose which provider handles transcript processing when it is enabled."
                value={transcriptProcessingProviderId}
                onChange={(value) => saveConfig({ transcriptPostProcessingProviderId: value as CHAT_PROVIDER_ID })}
                providers={CHAT_PROVIDERS}
                icon={FileText}
              />

              <div className="border-t px-3 py-2">
                {transcriptProcessingProviderId === "openai" ? (
                  <Control
                    label={<ControlLabel label="Transcript Processing model" tooltip="OpenAI-compatible transcript processing is selected through the preset section below." />}
                  >
                    <p className="text-sm text-muted-foreground">
                      OpenAI-compatible transcript processing models are selected in the OpenAI-Compatible Preset section below.
                    </p>
                  </Control>
                ) : (
                  <ModelSelector
                    providerId={transcriptProcessingProviderId}
                    value={transcriptProcessingModel}
                    onValueChange={(value) => {
                      if (transcriptProcessingProviderId === "groq") {
                        saveConfig({ transcriptPostProcessingGroqModel: value })
                      } else if (transcriptProcessingProviderId === "gemini") {
                        saveConfig({ transcriptPostProcessingGeminiModel: value })
                      } else {
                        saveConfig({ transcriptPostProcessingChatgptWebModel: value })
                      }
                    }}
                    label="Transcript Processing model"
                    placeholder="Select model for transcript processing"
                    excludeTranscriptionOnlyModels={true}
                  />
                )}
              </div>

              <Control
                label={<ControlLabel label="Prompt" tooltip="Custom prompt for transcript processing. Use {transcript} to insert the original transcript." />}
                className="border-t px-3 py-2"
              >
                <div className="w-full space-y-2">
                  <Textarea
                    rows={6}
                    value={transcriptProcessingPromptDraft}
                    onChange={(e) => updateTranscriptProcessingPromptDraft(e.currentTarget.value)}
                    onBlur={(e) => flushTranscriptProcessingPromptSave(e.currentTarget.value)}
                    placeholder="Custom instructions for transcript processing..."
                    className="min-h-[120px]"
                  />
                  <p className="text-xs text-muted-foreground">
                    Use <span className="select-text">{"{transcript}"}</span> to insert the original transcript.
                  </p>
                </div>
              </Control>
            </>
          )}
        </ControlGroup>

        <ControlGroup title="Speech & Voice Models" collapsible>
          <div className="px-3 py-2">
            {sttProviderId === "parakeet" ? (
              <Control
                label={<ControlLabel label="Speech-to-Text model" tooltip="Parakeet uses the local speech-to-text model bundle managed on the Providers page." />}
              >
                <p className="text-sm text-muted-foreground">
                  Parakeet uses its local downloaded model bundle. Manage installation and runtime settings on Providers.
                </p>
              </Control>
            ) : (
              <ModelSelector
                providerId={sttProviderId}
                value={sttProviderId === "openai" ? config.openaiSttModel || getDefaultSttModel("openai") : config.groqSttModel || getDefaultSttModel("groq")}
                onValueChange={(value) => saveConfig(sttProviderId === "openai" ? { openaiSttModel: value } : { groqSttModel: value })}
                label="Speech-to-Text model"
                placeholder="Select model for speech transcription"
                onlyTranscriptionModels={true}
              />
            )}
          </div>

          <div className="border-t px-3 py-2">
            <div className="pb-2">
              <span className="text-sm font-medium">Text-to-Speech model and voice</span>
              <p className="text-xs text-muted-foreground">
                Pick the voice stack for the currently selected text-to-speech provider.
              </p>
            </div>

            {ttsProviderId === "openai" && (
              <>
                <Control label={<ControlLabel label="Text-to-Speech model" tooltip="Choose the OpenAI TTS model to use." />}>
                  <Select value={config.openaiTtsModel || "gpt-4o-mini-tts"} onValueChange={(value) => saveConfig({ openaiTtsModel: value as "gpt-4o-mini-tts" | "tts-1" | "tts-1-hd" })}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {OPENAI_TTS_MODELS.map((model) => <SelectItem key={model.value} value={model.value}>{model.label}</SelectItem>)}
                    </SelectContent>
                  </Select>
                </Control>

                <Control label={<ControlLabel label="Text-to-Speech voice" tooltip="Choose the voice for OpenAI TTS." />}>
                  <Select value={config.openaiTtsVoice || "alloy"} onValueChange={(value) => saveConfig({ openaiTtsVoice: value as "alloy" | "echo" | "fable" | "onyx" | "nova" | "shimmer" })}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {OPENAI_TTS_VOICES.map((voice) => <SelectItem key={voice.value} value={voice.value}>{voice.label}</SelectItem>)}
                    </SelectContent>
                  </Select>
                </Control>

                <Control label={<ControlLabel label="Text-to-Speech speed" tooltip="Speech speed between 0.25 and 4.0." />}>
                  <Input
                    type="number"
                    min="0.25"
                    max="4.0"
                    step="0.25"
                    defaultValue={config.openaiTtsSpeed?.toString()}
                    placeholder="1.0"
                    onChange={(e) => {
                      const speed = parseFloat(e.currentTarget.value)
                      if (!isNaN(speed) && speed >= 0.25 && speed <= 4.0) {
                        saveConfig({ openaiTtsSpeed: speed })
                      }
                    }}
                  />
                </Control>
              </>
            )}

            {ttsProviderId === "groq" && (
              <>
                <Control label={<ControlLabel label="Text-to-Speech model" tooltip="Choose the Groq TTS model to use." />}>
                  <Select
                    value={config.groqTtsModel || "canopylabs/orpheus-v1-english"}
                    onValueChange={(value) => {
                      const defaultVoice = value === "canopylabs/orpheus-arabic-saudi" ? "fahad" : "troy"
                      saveConfig({ groqTtsModel: value as "canopylabs/orpheus-v1-english" | "canopylabs/orpheus-arabic-saudi", groqTtsVoice: defaultVoice })
                    }}
                  >
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {GROQ_TTS_MODELS.map((model) => <SelectItem key={model.value} value={model.value}>{model.label}</SelectItem>)}
                    </SelectContent>
                  </Select>
                </Control>

                <Control label={<ControlLabel label="Text-to-Speech voice" tooltip="Choose the voice for Groq TTS." />}>
                  <Select
                    value={config.groqTtsVoice || (config.groqTtsModel === "canopylabs/orpheus-arabic-saudi" ? "fahad" : "troy")}
                    onValueChange={(value) => saveConfig({ groqTtsVoice: value })}
                  >
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {(config.groqTtsModel === "canopylabs/orpheus-arabic-saudi" ? GROQ_TTS_VOICES_ARABIC : GROQ_TTS_VOICES_ENGLISH).map((voice) => (
                        <SelectItem key={voice.value} value={voice.value}>{voice.label}</SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </Control>
              </>
            )}

            {ttsProviderId === "gemini" && (
              <>
                <Control label={<ControlLabel label="Text-to-Speech model" tooltip="Choose the Gemini TTS model to use." />}>
                  <Select value={config.geminiTtsModel || "gemini-2.5-flash-preview-tts"} onValueChange={(value) => saveConfig({ geminiTtsModel: value as "gemini-2.5-flash-preview-tts" | "gemini-2.5-pro-preview-tts" })}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {GEMINI_TTS_MODELS.map((model) => <SelectItem key={model.value} value={model.value}>{model.label}</SelectItem>)}
                    </SelectContent>
                  </Select>
                </Control>

                <Control label={<ControlLabel label="Text-to-Speech voice" tooltip="Choose the voice for Gemini TTS." />}>
                  <Select value={config.geminiTtsVoice || "Kore"} onValueChange={(value) => saveConfig({ geminiTtsVoice: value })}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {GEMINI_TTS_VOICES.map((voice) => <SelectItem key={voice.value} value={voice.value}>{voice.label}</SelectItem>)}
                    </SelectContent>
                  </Select>
                </Control>
              </>
            )}

            {ttsProviderId === "edge" && (
              <>
                <Control label={<ControlLabel label="Text-to-Speech model" tooltip="Choose the Edge TTS model to use." />}>
                  <Select value={config.edgeTtsModel || "edge-tts"} onValueChange={(value) => saveConfig({ edgeTtsModel: value as "edge-tts" })}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {EDGE_TTS_MODELS.map((model) => <SelectItem key={model.value} value={model.value}>{model.label}</SelectItem>)}
                    </SelectContent>
                  </Select>
                </Control>

                <Control label={<ControlLabel label="Text-to-Speech voice" tooltip="Choose the voice for Edge TTS." />}>
                  <Select value={config.edgeTtsVoice || "en-US-AriaNeural"} onValueChange={(value) => saveConfig({ edgeTtsVoice: value })}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {EDGE_TTS_VOICES.map((voice) => <SelectItem key={voice.value} value={voice.value}>{voice.label}</SelectItem>)}
                    </SelectContent>
                  </Select>
                </Control>

                <Control label={<ControlLabel label="Text-to-Speech speed" tooltip="Speech speed between 0.5 and 2.0." />}>
                  <Input
                    type="number"
                    min="0.5"
                    max="2.0"
                    step="0.1"
                    defaultValue={config.edgeTtsRate?.toString()}
                    placeholder="1.0"
                    onChange={(e) => {
                      const speed = parseFloat(e.currentTarget.value)
                      if (!isNaN(speed) && speed >= 0.5 && speed <= 2.0) {
                        saveConfig({ edgeTtsRate: speed })
                      }
                    }}
                  />
                </Control>
                <p className="pb-2 text-xs text-muted-foreground">Edge TTS is cloud-based and does not require an API key.</p>
              </>
            )}

            {ttsProviderId === "kitten" && (
              <>
                <Control label={<ControlLabel label="Text-to-Speech voice" tooltip="Choose the local Kitten voice to use." />}>
                  <Select value={String(config.kittenVoiceId ?? 0)} onValueChange={(value) => saveConfig({ kittenVoiceId: parseInt(value) })}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {KITTEN_TTS_VOICES.map((voice) => <SelectItem key={voice.value} value={String(voice.value)}>{voice.label}</SelectItem>)}
                    </SelectContent>
                  </Select>
                </Control>
                <p className="pb-2 text-xs text-muted-foreground">Kitten download and voice testing live on Providers.</p>
              </>
            )}

            {ttsProviderId === "supertonic" && (
              <>
                <Control label={<ControlLabel label="Text-to-Speech voice" tooltip="Select the Supertonic voice style." />}>
                  <Select value={config.supertonicVoice ?? "M1"} onValueChange={(value) => saveConfig({ supertonicVoice: value })}>
                    <SelectTrigger className="w-full sm:w-[180px]"><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {SUPERTONIC_TTS_VOICES.map((voice) => <SelectItem key={voice.value} value={voice.value}>{voice.label}</SelectItem>)}
                    </SelectContent>
                  </Select>
                </Control>

                <Control label={<ControlLabel label="Language" tooltip="Select the language for speech synthesis." />}>
                  <Select value={config.supertonicLanguage ?? "en"} onValueChange={(value) => saveConfig({ supertonicLanguage: value })}>
                    <SelectTrigger className="w-full sm:w-[180px]"><SelectValue /></SelectTrigger>
                    <SelectContent>
                      {SUPERTONIC_TTS_LANGUAGES.map((language) => <SelectItem key={language.value} value={language.value}>{language.label}</SelectItem>)}
                    </SelectContent>
                  </Select>
                </Control>

                <Control label={<ControlLabel label="Speed" tooltip="Speech speed multiplier." />}>
                  <Input
                    type="number"
                    min={0.5}
                    max={2.0}
                    step={0.05}
                    className="w-full sm:w-[100px]"
                    value={config.supertonicSpeed ?? 1.05}
                    onChange={(e) => {
                      const val = parseFloat(e.currentTarget.value)
                      if (!isNaN(val) && val >= 0.5 && val <= 2.0) {
                        saveConfig({ supertonicSpeed: val })
                      }
                    }}
                  />
                </Control>

                <Control label={<ControlLabel label="Quality Steps" tooltip="Higher values improve quality but slow synthesis." />}>
                  <Input
                    type="number"
                    min={2}
                    max={10}
                    step={1}
                    className="w-full sm:w-[100px]"
                    value={config.supertonicSteps ?? 5}
                    onChange={(e) => {
                      const val = parseInt(e.currentTarget.value)
                      if (!isNaN(val) && val >= 2 && val <= 10) {
                        saveConfig({ supertonicSteps: val })
                      }
                    }}
                  />
                </Control>
                <p className="pb-2 text-xs text-muted-foreground">Supertonic downloads and quick voice tests live on Providers.</p>
              </>
            )}
          </div>
        </ControlGroup>

      </div>
    </div>
  )
}
