import { Component, For, Show } from 'solid-js';
import { appStore } from '../stores/appStore';
import { getModelDisplayName, MODELS } from './ModelLoadingOverlay';
import type { AudioEngine } from '../lib/audio/types';

const formatInterval = (ms: number) => {
  if (ms >= 1000) return `${(ms / 1000).toFixed(1)}s`;
  return `${ms}ms`;
};

export type SettingsPanelSection = 'full' | 'audio' | 'model';

export interface SettingsContentProps {
  /** When 'audio' or 'model', only that section is shown (e.g. hover on mic or load button). */
  section?: SettingsPanelSection;
  onClose: () => void;
  onLoadModel: () => void;
  onLocalLoad?: (files: FileList) => void;
  onOpenDebug: () => void;
  onDeviceSelect?: (id: string) => void;
  audioEngine?: AudioEngine | null;
  /** When true, panel expands upward (bar in lower half); content order is reversed so ASR model stays adjacent to the bar. */
  expandUp?: () => boolean;
}

/** Embeddable settings form (e.g. inside floating bar expansion). */
export const SettingsContent: Component<SettingsContentProps> = (props) => {
  const isV4 = () => appStore.transcriptionMode() === 'v4-utterance';
  const isV3 = () => appStore.transcriptionMode() === 'v3-streaming';

  const expandUp = () => props.expandUp?.() ?? false;
  const section = () => props.section ?? 'full';
  const showAsr = () => section() === 'full' || section() === 'model';
  const showAudio = () => section() === 'full' || section() === 'audio';
  const showSliders = () => section() === 'full';
  const showDebug = () => section() === 'full';

  return (
    <div class="flex flex-col min-h-0">
      <div
        class="flex flex-col flex-1 min-h-0 overflow-y-auto p-3 gap-4 custom-scrollbar"
        classList={{ 'flex-col-reverse': expandUp() }}
      >
        <Show when={showAsr()}>
          <section class="space-y-2">
            <h3 class="text-[10px] font-bold uppercase tracking-widest text-[var(--color-earthy-soft-brown)]">ASR model</h3>
            <div class="flex items-center gap-2 flex-wrap">
            <select
              class="flex-1 min-w-0 text-sm bg-transparent border-b border-[var(--color-earthy-sage)]/40 px-0 py-1.5 text-[var(--color-earthy-dark-brown)] focus:outline-none focus:border-[var(--color-earthy-muted-green)]"
              value={appStore.selectedModelId()}
              onInput={(e) => appStore.setSelectedModelId((e.target as HTMLSelectElement).value)}
              disabled={appStore.modelState() === 'loading'}
            >
              <For each={MODELS}>
                {(m) => <option value={m.id}>{m.name}</option>}
              </For>
            </select>
            <button
              type="button"
              onClick={props.onLoadModel}
              disabled={appStore.modelState() === 'ready' || appStore.modelState() === 'loading'}
              class="flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-[var(--color-earthy-muted-green)] hover:bg-[var(--color-earthy-sage)]/20 transition-colors disabled:opacity-50 disabled:cursor-not-allowed shrink-0"
            >
              <span class="material-symbols-outlined text-lg">power_settings_new</span>
              {appStore.modelState() === 'ready' ? 'Loaded' : appStore.modelState() === 'loading' ? '...' : 'Load'}
            </button>
            <Show when={props.onLocalLoad}>
              <label class="flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-[var(--color-earthy-soft-brown)] hover:bg-[var(--color-earthy-sage)]/20 transition-colors cursor-pointer shrink-0">
                <span class="material-symbols-outlined text-lg">folder_open</span>
                Load from file
                <input
                  type="file"
                  multiple
                  class="hidden"
                  accept=".onnx,.bin"
                  onChange={(e) => {
                    const files = e.currentTarget.files;
                    if (files && files.length > 0) props.onLocalLoad?.(files);
                    e.currentTarget.value = '';
                  }}
                />
              </label>
            </Show>
          </div>
          <p class="text-xs text-[var(--color-earthy-soft-brown)]">
            {appStore.modelState() === 'ready' ? getModelDisplayName(appStore.selectedModelId()) : appStore.modelState()}
          </p>
          <Show when={appStore.modelState() === 'loading'}>
            <div class="space-y-1">
              <div class="flex justify-between text-xs">
                <span>{appStore.modelMessage()}</span>
                <span class="font-mono text-[var(--color-earthy-muted-green)]">{Math.round(appStore.modelProgress())}%</span>
              </div>
              <div class="h-1.5 rounded-full overflow-hidden bg-[var(--color-earthy-sage)]/20">
                <div
                  class="h-full bg-[var(--color-earthy-muted-green)] rounded-full transition-all duration-300"
                  style={{ width: `${Math.max(0, Math.min(100, appStore.modelProgress()))}%` }}
                />
              </div>
            </div>
          </Show>
          </section>
        </Show>

        <Show when={showAudio()}>
          <section class="space-y-2">
          <h3 class="text-[10px] font-bold uppercase tracking-widest text-[var(--color-earthy-soft-brown)]">Audio input</h3>
          <select
            class="w-full text-sm bg-transparent border-b border-[var(--color-earthy-sage)]/40 px-0 py-1.5 text-[var(--color-earthy-dark-brown)] focus:outline-none focus:border-[var(--color-earthy-muted-green)]"
            value={appStore.selectedDeviceId()}
            onInput={(e) => {
              const id = (e.target as HTMLSelectElement).value;
              appStore.setSelectedDeviceId(id);
              props.onDeviceSelect?.(id);
            }}
          >
            <For each={appStore.availableDevices()}>
              {(device) => (
                <option value={device.deviceId}>
                  {device.label || `Device ${device.deviceId.slice(0, 8)}`}
                </option>
              )}
            </For>
          </select>
          </section>
        </Show>

        <Show when={showSliders()}>
          <section class="grid grid-cols-2 gap-x-4 gap-y-3">
          <div class="space-y-1.5 min-w-0">
            <div class="flex justify-between items-center gap-2">
              <span class="text-[10px] font-bold uppercase tracking-widest text-[var(--color-earthy-soft-brown)]">Energy threshold</span>
              <span class="text-sm text-[var(--color-earthy-dark-brown)] tabular-nums shrink-0">{(appStore.energyThreshold() * 100).toFixed(1)}%</span>
            </div>
            <input
              type="range" min="0.005" max="0.3" step="0.005"
              value={appStore.energyThreshold()}
              onInput={(e) => {
                const val = parseFloat(e.currentTarget.value);
                appStore.setEnergyThreshold(val);
                props.audioEngine?.updateConfig({ energyThreshold: val });
              }}
              class="debug-slider w-full h-2 rounded-full appearance-none cursor-pointer bg-[var(--color-earthy-sage)]/30"
            />
          </div>

          <Show when={isV4()}>
            <div class="space-y-1.5 min-w-0">
              <div class="flex justify-between items-center gap-2">
                <span class="text-[10px] font-bold uppercase tracking-widest text-[var(--color-earthy-soft-brown)]">VAD threshold</span>
                <span class="text-sm text-[var(--color-earthy-dark-brown)] tabular-nums shrink-0">{(appStore.sileroThreshold() * 100).toFixed(0)}%</span>
              </div>
              <input
                type="range" min="0.1" max="0.9" step="0.05"
                value={appStore.sileroThreshold()}
                onInput={(e) => appStore.setSileroThreshold(parseFloat(e.currentTarget.value))}
                class="debug-slider w-full h-2 rounded-full appearance-none cursor-pointer bg-[var(--color-earthy-sage)]/30"
              />
            </div>
            <div class="space-y-1.5 min-w-0">
              <div class="flex justify-between items-center gap-2">
                <span class="text-[10px] font-bold uppercase tracking-widest text-[var(--color-earthy-soft-brown)]">Tick interval</span>
                <span class="text-sm text-[var(--color-earthy-dark-brown)] tabular-nums shrink-0">{formatInterval(appStore.v4InferenceIntervalMs())}</span>
              </div>
              <input
                type="range" min="160" max="8000" step="80"
                value={appStore.v4InferenceIntervalMs()}
                onInput={(e) => appStore.setV4InferenceIntervalMs(parseInt(e.currentTarget.value))}
                class="debug-slider w-full h-2 rounded-full appearance-none cursor-pointer bg-[var(--color-earthy-sage)]/30"
              />
              <div class="flex justify-between text-[9px] text-[var(--color-earthy-soft-brown)]">
                <span>320ms</span>
                <span>8.0s</span>
              </div>
            </div>
            <div class="space-y-1.5 min-w-0">
              <div class="flex justify-between items-center gap-2">
                <span class="text-[10px] font-bold uppercase tracking-widest text-[var(--color-earthy-soft-brown)]">Silence flush</span>
                <span class="text-sm text-[var(--color-earthy-dark-brown)] tabular-nums shrink-0">{appStore.v4SilenceFlushSec().toFixed(1)}s</span>
              </div>
              <input
                type="range" min="0.3" max="5.0" step="0.1"
                value={appStore.v4SilenceFlushSec()}
                onInput={(e) => appStore.setV4SilenceFlushSec(parseFloat(e.currentTarget.value))}
                class="debug-slider w-full h-2 rounded-full appearance-none cursor-pointer bg-[var(--color-earthy-sage)]/30"
              />
            </div>
          </Show>

          <Show when={isV3()}>
            <div class="space-y-1.5 min-w-0">
              <div class="flex justify-between items-center gap-2">
                <span class="text-[10px] font-bold uppercase tracking-widest text-[var(--color-earthy-soft-brown)]">Window</span>
                <span class="text-sm text-[var(--color-earthy-dark-brown)] tabular-nums shrink-0">{appStore.streamingWindow().toFixed(1)}s</span>
              </div>
              <input
                type="range" min="2.0" max="15.0" step="0.5"
                value={appStore.streamingWindow()}
                onInput={(e) => appStore.setStreamingWindow(parseFloat(e.currentTarget.value))}
                class="debug-slider w-full h-2 rounded-full appearance-none cursor-pointer bg-[var(--color-earthy-sage)]/30"
              />
            </div>
          </Show>
          </section>
        </Show>

        <Show when={showDebug()}>
          <div class="pt-2">
            <button
              type="button"
              onClick={() => {
                props.onOpenDebug();
                props.onClose();
              }}
              class="flex items-center gap-2 px-0 py-2 text-sm font-medium text-[var(--color-earthy-muted-green)] hover:opacity-80 transition-opacity w-full"
            >
              <span class="material-symbols-outlined text-lg">bug_report</span>
              Open Debug panel
            </button>
          </div>
        </Show>
      </div>
    </div>
  );
};
