import { useEffect, useRef, useState } from 'react';
import { Command } from 'cmdk';
import { Bug, Clock, Keyboard, KeyRound, MessageSquare, Mic, Palette, Plus, RefreshCw, User, Volume2, X, Zap } from 'lucide-react';
import { useUiStore } from '../store/uiStore';
import { useVoiceStore } from '../store/voiceStore';
import { useUiClientConfig } from '../context/UiClientContext';
import { VoiceModelPicker } from './VoiceModelPicker';
import { isDebugLogEnabled, toggleDebugLog } from '../utils/debugLog';

interface ShortcutGatewayProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onStartNewSession: () => void;
  onSelectTheme: () => void;
  onAuthenticateProvider: () => void;
  onUpdatePlugins: () => void;
  onCreateSchedule: () => void;
  hasProfiles: boolean;
  onOpenProfiles: () => void;
  isUpdatingPlugins?: boolean;
}

export function ShortcutGateway({
  open,
  onOpenChange,
  onStartNewSession,
  onSelectTheme,
  onAuthenticateProvider,
  onUpdatePlugins,
  onCreateSchedule,
  hasProfiles,
  onOpenProfiles,
  isUpdatingPlugins = false,
}: ShortcutGatewayProps) {
  const [search, setSearch] = useState('');
  const inputRef = useRef<HTMLInputElement>(null);
  const { focusMainInput, followNewMessages, setFollowNewMessages, perfMode, togglePerfMode } = useUiStore();
  const { audioCapabilities } = useUiClientConfig();
  const {
    sttProvider, sttModel, ttsProvider, ttsModel, ttsVoice,
    setSttConfig, setTtsConfig, autoTtsEnabled, setAutoTtsEnabled,
  } = useVoiceStore();
  const [sttPickerOpen, setSttPickerOpen] = useState(false);
  const [ttsPickerOpen, setTtsPickerOpen] = useState(false);
  const shortcutGatewayPrefix = navigator.platform.includes('Mac') ? '⌘+X' : 'Ctrl+X';
  const hasAudio = audioCapabilities.stt_models.length > 0 || audioCapabilities.tts_models.length > 0;

  const close = () => {
    onOpenChange(false);
    focusMainInput();
  };

  useEffect(() => {
    if (!open) {
      return;
    }
    setSearch('');
    setSttPickerOpen(false);
    setTtsPickerOpen(false);
    window.setTimeout(() => inputRef.current?.focus(), 0);
  }, [open]);

  return (
    <>
      {open && (<>
      <div
        data-testid="shortcut-gateway-backdrop"
        className="fixed inset-0 bg-surface-canvas/80 z-40 animate-fade-in"
        onClick={close}
      />

      <div
        data-testid="shortcut-gateway-container"
        className="fixed inset-0 z-50 flex items-start justify-center pt-[18vh] px-4"
        onClick={(e) => {
          if (e.target === e.currentTarget) {
            close();
          }
        }}
      >
        <Command
          label="Shortcut gateway"
          className="w-full max-w-2xl bg-surface-elevated border-2 border-accent-primary/30 rounded-xl shadow-[0_0_40px_rgba(var(--accent-primary-rgb),0.22)] overflow-hidden animate-scale-in"
        >
          <div className="flex items-center justify-between gap-3 px-4 py-3 border-b border-surface-border/60">
            <div className="flex items-center gap-2 text-accent-primary">
              <Keyboard className="w-4 h-4" />
              <span className="text-sm font-medium">Shortcut Gateway</span>
            </div>
            <div className="flex items-center gap-2">
              <button
                type="button"
                onClick={close}
                className="sm:hidden p-1.5 rounded hover:bg-surface-canvas transition-colors text-ui-secondary hover:text-ui-primary"
                aria-label="Close"
              >
                <X className="w-5 h-5" />
              </button>
              <kbd className="hidden sm:inline-block px-2 py-1 text-[10px] font-mono bg-surface-canvas border border-surface-border rounded text-ui-muted">
                ESC
              </kbd>
            </div>
          </div>

          <div className="flex items-center gap-2 px-4 py-2.5 border-b border-surface-border/40">
            <span className="text-xs text-ui-muted font-mono">{shortcutGatewayPrefix}</span>
            <Command.Input
              ref={inputRef}
              value={search}
              onValueChange={setSearch}
              placeholder="Type command or use Up/Down then Enter..."
              className="flex-1 bg-transparent text-ui-primary placeholder:text-ui-muted text-sm focus:outline-none"
            />
          </div>

          <Command.List className="max-h-[360px] overflow-y-auto p-2 custom-scrollbar">
            <Command.Empty className="px-4 py-6 text-sm text-center text-ui-muted">
              No shortcut commands found
            </Command.Empty>

            <Command.Group className="mb-1">
              <Command.Item
                value="start new session"
                keywords={['new', 'session', 'start', 'n']}
                onSelect={() => onStartNewSession()}
                className="flex items-center gap-3 px-3 py-2.5 rounded-lg border border-surface-border/20 cursor-pointer transition-colors data-[selected=true]:bg-accent-primary/15 data-[selected=true]:border-accent-primary/35 hover:bg-surface-elevated/60 hover:border-surface-border/40"
              >
                <div className="w-7 h-7 rounded-md border border-accent-primary/35 bg-accent-primary/10 flex items-center justify-center">
                  <Plus className="w-3.5 h-3.5 text-accent-primary" />
                </div>
                <div className="flex-1 min-w-0">
                  <div className="text-sm text-ui-primary">Start New Session</div>
                  <div className="text-xs text-ui-muted">Create a fresh session and jump in</div>
                </div>
                <kbd className="px-2 py-1 text-[10px] font-mono bg-surface-canvas border border-surface-border rounded text-ui-secondary">
                  N
                </kbd>
              </Command.Item>

              <Command.Item
                value="follow new messages"
                keywords={['follow', 'messages', 'scroll', 'auto']}
                onSelect={() => setFollowNewMessages(!followNewMessages)}
                className="flex items-center gap-3 px-3 py-2.5 rounded-lg border border-surface-border/20 cursor-pointer transition-colors data-[selected=true]:bg-accent-primary/15 data-[selected=true]:border-accent-primary/35 hover:bg-surface-elevated/60 hover:border-surface-border/40"
              >
                <div className="w-7 h-7 rounded-md border border-accent-primary/35 bg-accent-primary/10 flex items-center justify-center">
                  <MessageSquare className="w-3.5 h-3.5 text-accent-primary" />
                </div>
                <div className="flex-1 min-w-0">
                  <div className="text-sm text-ui-primary">Follow New Messages</div>
                  <div className="text-xs text-ui-muted">
                    {followNewMessages ? 'Auto-scroll to newest message is enabled' : 'Auto-scroll is paused'}
                  </div>
                </div>
                <kbd className="px-2 py-1 text-[10px] font-mono bg-surface-canvas border border-surface-border rounded text-ui-secondary">
                  {followNewMessages ? 'On' : 'Off'}
                </kbd>
              </Command.Item>

              <Command.Item
                value="theme selector"
                keywords={['theme', 'themes', 't', 'palette']}
                onSelect={() => onSelectTheme()}
                className="flex items-center gap-3 px-3 py-2.5 rounded-lg border border-surface-border/20 cursor-pointer transition-colors data-[selected=true]:bg-accent-primary/15 data-[selected=true]:border-accent-primary/35 hover:bg-surface-elevated/60 hover:border-surface-border/40"
              >
                <div className="w-7 h-7 rounded-md border border-accent-primary/35 bg-accent-primary/10 flex items-center justify-center">
                  <Palette className="w-3.5 h-3.5 text-accent-primary" />
                </div>
                <div className="flex-1 min-w-0">
                  <div className="text-sm text-ui-primary">Theme Selector</div>
                  <div className="text-xs text-ui-muted">Open searchable theme switcher</div>
                </div>
                <kbd className="px-2 py-1 text-[10px] font-mono bg-surface-canvas border border-surface-border rounded text-ui-secondary">
                  T
                </kbd>
              </Command.Item>

              <Command.Item
                value="authenticate provider"
                keywords={['auth', 'oauth', 'provider', 'login', 'a']}
                onSelect={() => onAuthenticateProvider()}
                className="flex items-center gap-3 px-3 py-2.5 rounded-lg border border-surface-border/20 cursor-pointer transition-colors data-[selected=true]:bg-accent-primary/15 data-[selected=true]:border-accent-primary/35 hover:bg-surface-elevated/60 hover:border-surface-border/40"
              >
                <div className="w-7 h-7 rounded-md border border-accent-primary/35 bg-accent-primary/10 flex items-center justify-center">
                  <KeyRound className="w-3.5 h-3.5 text-accent-primary" />
                </div>
                <div className="flex-1 min-w-0">
                  <div className="text-sm text-ui-primary">Authenticate Provider</div>
                  <div className="text-xs text-ui-muted">Sign in with OAuth and unlock provider models</div>
                </div>
                <kbd className="px-2 py-1 text-[10px] font-mono bg-surface-canvas border border-surface-border rounded text-ui-secondary">
                  A
                </kbd>
              </Command.Item>

              {hasProfiles && (
                <Command.Item
                  value="profile selector"
                  keywords={['profile', 'profiles', 'switch', 'p']}
                  onSelect={() => onOpenProfiles()}
                  className="flex items-center gap-3 px-3 py-2.5 rounded-lg border border-surface-border/20 cursor-pointer transition-colors data-[selected=true]:bg-accent-primary/15 data-[selected=true]:border-accent-primary/35 hover:bg-surface-elevated/60 hover:border-surface-border/40"
                >
                  <div className="w-7 h-7 rounded-md border border-accent-primary/35 bg-accent-primary/10 flex items-center justify-center">
                    <User className="w-3.5 h-3.5 text-accent-primary" />
                  </div>
                  <div className="flex-1 min-w-0">
                    <div className="text-sm text-ui-primary">Profiles</div>
                    <div className="text-xs text-ui-muted">Switch active profile for new sessions</div>
                  </div>
                  <kbd className="px-2 py-1 text-[10px] font-mono bg-surface-canvas border border-surface-border rounded text-ui-secondary">
                    P
                  </kbd>
                </Command.Item>
              )}

              <Command.Item
                value="update provider plugins"
                keywords={['update', 'plugin', 'plugins', 'oci', 'provider', 'u']}
                onSelect={() => onUpdatePlugins()}
                className="flex items-center gap-3 px-3 py-2.5 rounded-lg border border-surface-border/20 cursor-pointer transition-colors data-[selected=true]:bg-accent-primary/15 data-[selected=true]:border-accent-primary/35 hover:bg-surface-elevated/60 hover:border-surface-border/40"
              >
                <div className="w-7 h-7 rounded-md border border-accent-primary/35 bg-accent-primary/10 flex items-center justify-center">
                  <RefreshCw className={`w-3.5 h-3.5 text-accent-primary ${isUpdatingPlugins ? 'animate-spin' : ''}`} />
                </div>
                <div className="flex-1 min-w-0">
                  <div className="text-sm text-ui-primary">Update Provider Plugins</div>
                  <div className="text-xs text-ui-muted">Pull latest OCI plugin images from registry</div>
                </div>
                <kbd className="px-2 py-1 text-[10px] font-mono bg-surface-canvas border border-surface-border rounded text-ui-secondary">
                  {isUpdatingPlugins ? 'Updating...' : 'U'}
                </kbd>
              </Command.Item>

              <Command.Item
                value="create schedule"
                keywords={['schedule', 'cron', 'recurring', 'task', 'automation', 's']}
                onSelect={() => onCreateSchedule()}
                className="flex items-center gap-3 px-3 py-2.5 rounded-lg border border-surface-border/20 cursor-pointer transition-colors data-[selected=true]:bg-accent-primary/15 data-[selected=true]:border-accent-primary/35 hover:bg-surface-elevated/60 hover:border-surface-border/40"
              >
                <div className="w-7 h-7 rounded-md border border-accent-primary/35 bg-accent-primary/10 flex items-center justify-center">
                  <Clock className="w-3.5 h-3.5 text-accent-primary" />
                </div>
                <div className="flex-1 min-w-0">
                  <div className="text-sm text-ui-primary">Create Schedule</div>
                  <div className="text-xs text-ui-muted">Set up a scheduled task for the current session</div>
                </div>
                <kbd className="px-2 py-1 text-[10px] font-mono bg-surface-canvas border border-surface-border rounded text-ui-secondary">
                  S
                </kbd>
              </Command.Item>

              <Command.Item
                value="debug logging"
                keywords={['debug', 'log', 'logging', 'console', 'verbose', 'd']}
                onSelect={() => { toggleDebugLog(); close(); }}
                className="flex items-center gap-3 px-3 py-2.5 rounded-lg border border-surface-border/20 cursor-pointer transition-colors data-[selected=true]:bg-accent-primary/15 data-[selected=true]:border-accent-primary/35 hover:bg-surface-elevated/60 hover:border-surface-border/40"
              >
                <div className="w-7 h-7 rounded-md border border-accent-primary/35 bg-accent-primary/10 flex items-center justify-center">
                  <Bug className="w-3.5 h-3.5 text-accent-primary" />
                </div>
                <div className="flex-1 min-w-0">
                  <div className="text-sm text-ui-primary">Debug Logging</div>
                  <div className="text-xs text-ui-muted">
                    {isDebugLogEnabled() ? 'Verbose console logging is enabled' : 'Toggle verbose console logging for diagnostics'}
                  </div>
                </div>
                <kbd className="px-2 py-1 text-[10px] font-mono bg-surface-canvas border border-surface-border rounded text-ui-secondary">
                  {isDebugLogEnabled() ? 'On' : 'D'}
                </kbd>
              </Command.Item>

              <Command.Item
                value="performance mode"
                keywords={['perf', 'performance', 'gpu', 'power', 'battery', 'g']}
                onSelect={() => { togglePerfMode(); close(); }}
                className="flex items-center gap-3 px-3 py-2.5 rounded-lg border border-surface-border/20 cursor-pointer transition-colors data-[selected=true]:bg-accent-primary/15 data-[selected=true]:border-accent-primary/35 hover:bg-surface-elevated/60 hover:border-surface-border/40"
              >
                <div className="w-7 h-7 rounded-md border border-accent-primary/35 bg-accent-primary/10 flex items-center justify-center">
                  <Zap className="w-3.5 h-3.5 text-accent-primary" />
                </div>
                <div className="flex-1 min-w-0">
                  <div className="text-sm text-ui-primary">Performance Mode</div>
                  <div className="text-xs text-ui-muted">
                    {perfMode ? 'Animations, glows and blur effects disabled' : 'Disable GPU-intensive effects for lower power usage'}
                  </div>
                </div>
                <kbd className="px-2 py-1 text-[10px] font-mono bg-surface-canvas border border-surface-border rounded text-ui-secondary">
                  {perfMode ? 'On' : 'G'}
                </kbd>
              </Command.Item>
            </Command.Group>


            {hasAudio && (
              <Command.Group heading={<span className="text-[11px] font-medium text-ui-muted px-1 uppercase tracking-wider">Voice</span>} className="mt-2 mb-1">
                {audioCapabilities.stt_models.length > 0 && (
                  <Command.Item
                    value="stt model voice"
                    keywords={['stt', 'speech', 'transcribe', 'microphone', 'voice', 'asr']}
                    onSelect={() => { onOpenChange(false); setSttPickerOpen(true); }}
                    className="flex items-center gap-3 px-3 py-2.5 rounded-lg border border-surface-border/20 cursor-pointer transition-colors data-[selected=true]:bg-accent-primary/15 data-[selected=true]:border-accent-primary/35 hover:bg-surface-elevated/60 hover:border-surface-border/40"
                  >
                    <div className="w-7 h-7 rounded-md border border-accent-primary/35 bg-accent-primary/10 flex items-center justify-center">
                      <Mic className="w-3.5 h-3.5 text-accent-primary" />
                    </div>
                    <div className="flex-1 min-w-0">
                      <div className="text-sm text-ui-primary">STT Model</div>
                      <div className="text-xs text-ui-muted truncate">
                        {sttProvider}/{sttModel}
                      </div>
                    </div>
                  </Command.Item>
                )}

                {audioCapabilities.tts_models.length > 0 && (
                  <Command.Item
                    value="tts model voice"
                    keywords={['tts', 'speech', 'speak', 'voice', 'synthesis']}
                    onSelect={() => { onOpenChange(false); setTtsPickerOpen(true); }}
                    className="flex items-center gap-3 px-3 py-2.5 rounded-lg border border-surface-border/20 cursor-pointer transition-colors data-[selected=true]:bg-accent-primary/15 data-[selected=true]:border-accent-primary/35 hover:bg-surface-elevated/60 hover:border-surface-border/40"
                  >
                    <div className="w-7 h-7 rounded-md border border-accent-primary/35 bg-accent-primary/10 flex items-center justify-center">
                      <Volume2 className="w-3.5 h-3.5 text-accent-primary" />
                    </div>
                    <div className="flex-1 min-w-0">
                      <div className="text-sm text-ui-primary">TTS Model</div>
                      <div className="text-xs text-ui-muted truncate">
                        {ttsProvider}/{ttsModel}{ttsVoice ? ` (${ttsVoice})` : ''}
                      </div>
                    </div>
                  </Command.Item>
                )}

                {audioCapabilities.tts_models.length > 0 && (
                  <Command.Item
                    value="auto tts voice"
                    keywords={['auto', 'tts', 'speak', 'voice', 'auto-speak']}
                    onSelect={() => setAutoTtsEnabled(!autoTtsEnabled)}
                    className="flex items-center gap-3 px-3 py-2.5 rounded-lg border border-surface-border/20 cursor-pointer transition-colors data-[selected=true]:bg-accent-primary/15 data-[selected=true]:border-accent-primary/35 hover:bg-surface-elevated/60 hover:border-surface-border/40"
                  >
                    <div className="w-7 h-7 rounded-md border border-accent-primary/35 bg-accent-primary/10 flex items-center justify-center">
                      <Volume2 className="w-3.5 h-3.5 text-accent-primary" />
                    </div>
                    <div className="flex-1 min-w-0">
                      <div className="text-sm text-ui-primary">Auto-TTS</div>
                      <div className="text-xs text-ui-muted">
                        {autoTtsEnabled ? 'Agent responses are spoken aloud' : 'Speak agent responses automatically'}
                      </div>
                    </div>
                    <kbd className="px-2 py-1 text-[10px] font-mono bg-surface-canvas border border-surface-border rounded text-ui-secondary">
                      {autoTtsEnabled ? 'On' : 'Off'}
                    </kbd>
                  </Command.Item>
                )}
              </Command.Group>
            )}
          </Command.List>
        </Command>
      </div>
      </>)}

      <VoiceModelPicker
        open={sttPickerOpen}
        onOpenChange={setSttPickerOpen}
        mode="stt"
        models={audioCapabilities.stt_models}
        selectedProvider={sttProvider}
        selectedModel={sttModel}
        onSelect={setSttConfig}
      />

      <VoiceModelPicker
        open={ttsPickerOpen}
        onOpenChange={setTtsPickerOpen}
        mode="tts"
        models={audioCapabilities.tts_models}
        selectedProvider={ttsProvider}
        selectedModel={ttsModel}
        onSelect={setTtsConfig}
      />
    </>
  );
}
