import { For, Show, type Component, type JSX, createMemo, createSignal } from "solid-js"
import { ButtonV2 } from "@opencode-ai/ui/v2/button-v2"
import { SelectV2 } from "@opencode-ai/ui/v2/select-v2"
import { Switch } from "@opencode-ai/ui/v2/switch-v2"
import { TextInputV2 } from "@opencode-ai/ui/v2/text-input-v2"
import { useLanguage } from "@/context/language"
import { usePlatform } from "@/context/platform"
import { SettingsListV2 } from "@/components/settings-v2/parts/list"
import { SettingsRowV2 } from "@/components/settings-v2/parts/row"
import { Link } from "@/components/link"
import { useVoice } from "./voice-context"
import type { VoiceProvider } from "./types"

const PROVIDERS: Array<{ id: VoiceProvider; label: string; docs: string }> = [
  { id: "deepgram", label: "Deepgram", docs: "https://console.deepgram.com/" },
  { id: "groq", label: "Groq Whisper", docs: "https://console.groq.com/keys" },
  { id: "openai-whisper", label: "OpenAI Whisper", docs: "https://platform.openai.com/api-keys" },
]

export const VoiceSettings: Component = () => {
  const voice = useVoice()
  const language = useLanguage()
  const platform = usePlatform()
  const [testing, setTesting] = createSignal(false)
  const [testMessage, setTestMessage] = createSignal<string>()

  const provider = createMemo(() => PROVIDERS.find((item) => item.id === voice.config().provider) ?? PROVIDERS[0])
  const providerOptions = () => PROVIDERS

  return (
    <Show
      when={platform.platform === "desktop" && voice.available()}
      fallback={
        <SettingsSection title={language.t("settings.voice.title")}>
          <SettingsRowV2
            title={language.t("settings.voice.unavailable.title")}
            description={language.t("settings.voice.unavailable.description")}
          >
            <span />
          </SettingsRowV2>
        </SettingsSection>
      }
    >
      <div class="flex flex-col gap-6">
        <SettingsSection title={language.t("settings.voice.title")}>
          <SettingsRowV2
            title={language.t("settings.voice.enabled.title")}
            description={language.t("settings.voice.enabled.description")}
          >
            <div class="flex items-center">
              <Switch checked={voice.config().enabled} onChange={(checked) => void voice.setConfig({ enabled: checked })} />
            </div>
          </SettingsRowV2>

          <SettingsRowV2
            title={language.t("settings.voice.provider.title")}
            description={language.t("settings.voice.provider.description")}
          >
            <SelectV2
              appearance="inline"
              options={providerOptions()}
              current={provider()}
              placement="bottom-end"
              gutter={6}
              value={(o) => o.id}
              label={(o) => o.label}
              onSelect={(option) => {
                if (!option) return
                void voice.setConfig({ provider: option.id })
              }}
            />
          </SettingsRowV2>

          <SettingsRowV2
            title={language.t("settings.voice.language.title")}
            description={language.t("settings.voice.language.description")}
          >
            <div class="w-full sm:w-[220px]">
              <TextInputV2
                type="text"
                appearance="base"
                value={voice.config().language}
                placeholder="en"
                onInput={(event) => void voice.setConfig({ language: event.currentTarget.value || "en" })}
              />
            </div>
          </SettingsRowV2>

          <SettingsRowV2
            title={language.t("settings.voice.hotkey.title")}
            description={language.t("settings.voice.hotkey.description")}
          >
            <div class="w-full sm:w-[220px]">
              <TextInputV2
                type="text"
                appearance="base"
                value={voice.config().hotkey}
                placeholder="Alt+Space"
                onInput={(event) => void voice.setConfig({ hotkey: event.currentTarget.value || "Alt+Space" })}
              />
            </div>
          </SettingsRowV2>

          <SettingsRowV2
            title={language.t("settings.voice.commands.title")}
            description={language.t("settings.voice.commands.description")}
          >
            <div class="flex items-center">
              <Switch
                checked={voice.config().commands}
                onChange={(checked) => void voice.setConfig({ commands: checked })}
              />
            </div>
          </SettingsRowV2>

          <SettingsRowV2
            title={language.t("settings.voice.autoSend.title")}
            description={language.t("settings.voice.autoSend.description")}
          >
            <div class="flex items-center">
              <Switch
                checked={voice.config().autoSend}
                onChange={(checked) => void voice.setConfig({ autoSend: checked })}
              />
            </div>
          </SettingsRowV2>
        </SettingsSection>

        <SettingsSection title={language.t("settings.voice.api.title")}>
          <SettingsRowV2
            title={language.t("settings.voice.api.status.title")}
            description={
              voice.config().apiKeyConfigured
                ? language.t("settings.voice.api.status.configured", { env: voice.config().apiKeyEnv })
                : language.t("settings.voice.api.status.missing", { env: voice.config().apiKeyEnv })
            }
          >
            <span
              class="text-12-medium"
              style={{
                color: voice.config().apiKeyConfigured ? "var(--color-success, #22c55e)" : "var(--color-danger, #ef4444)",
              }}
            >
              {voice.config().apiKeyConfigured
                ? language.t("settings.voice.api.ready")
                : language.t("settings.voice.api.missing")}
            </span>
          </SettingsRowV2>

          <SettingsRowV2
            title={language.t("settings.voice.api.docs.title")}
            description={language.t("settings.voice.api.docs.description")}
          >
            <Link href={provider().docs}>{provider().label}</Link>
          </SettingsRowV2>

          <SettingsRowV2
            title={language.t("settings.voice.test.title")}
            description={language.t("settings.voice.test.description")}
          >
            <ButtonV2
              size="small"
              disabled={testing() || !voice.config().enabled}
              onClick={async () => {
                setTesting(true)
                setTestMessage(undefined)
                try {
                  await voice.start()
                  setTestMessage(language.t("settings.voice.test.started"))
                  setTimeout(() => void voice.stop(), 3000)
                } catch (error) {
                  setTestMessage(error instanceof Error ? error.message : String(error))
                } finally {
                  setTesting(false)
                }
              }}
            >
              {language.t("settings.voice.test.action")}
            </ButtonV2>
          </SettingsRowV2>

          <Show when={testMessage()}>
            <div class="px-3 text-12-regular text-text-weak">{testMessage()}</div>
          </Show>
        </SettingsSection>

        <SettingsSection title={language.t("settings.voice.commands.list.title")}>
          <For
            each={
              [
                ["send / submit / go", "voice.command.send"],
                ["run / execute", "voice.command.run"],
                ["accept / approve / yes", "voice.command.accept"],
                ["reject / deny / no", "voice.command.reject"],
                ["clear / reset / erase", "voice.command.clear"],
                ["stop / cancel / abort", "voice.command.stop"],
                ["scroll up / scroll down", "voice.command.scroll"],
                ["focus", "voice.command.focus"],
                ["new line / line break", "voice.command.newline"],
              ] as const
            }
          >
            {([phrase, key]) => (
              <SettingsRowV2 title={phrase} description={language.t(key)}>
                <span />
              </SettingsRowV2>
            )}
          </For>
        </SettingsSection>
      </div>
    </Show>
  )
}

const SettingsSection: Component<{ title: string; children: JSX.Element }> = (props) => (
  <section class="flex flex-col gap-2">
    <h2 class="text-14-medium text-text-strong">{props.title}</h2>
    <SettingsListV2>{props.children}</SettingsListV2>
  </section>
)
