import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { ConfigManager } from '../../../core/config/ConfigManager';

const GeneralSettings: React.FC = () => {
  const [llmProvider, setLlmProvider] = useState<string>('openai');
  const [openaiKey, setOpenaiKey] = useState<string>('');
  const [openaiModel, setOpenaiModel] = useState<string>('');
  const [geminiKey, setGeminiKey] = useState<string>('');
  const [geminiModel, setGeminiModel] = useState<string>('');
  const [claudeKey, setClaudeKey] = useState<string>('');
  const [claudeModel, setClaudeModel] = useState<string>('');
  const [openaiFlex, setOpenaiFlex] = useState<boolean>(false);
  const [compatibleKey, setCompatibleKey] = useState<string>('');
  const [compatibleBaseUrl, setCompatibleBaseUrl] = useState<string>('');
  const [compatibleModel, setCompatibleModel] = useState<string>('');
  const [soundfontBaseUrl, setSoundfontBaseUrl] = useState<string>('');

  const configManager = ConfigManager.instance();

  const isLocalEnvironment = useMemo(() => {
    try {
      if (typeof window === 'undefined' || typeof window.location === 'undefined') {
        return false;
      }
      const { protocol, hostname } = window.location;
      if (protocol === 'file:') return true;
      const localHosts = new Set(['localhost', '127.0.0.1', '::1', '0.0.0.0']);
      return localHosts.has(hostname);
    } catch {
      return false;
    }
  }, []);

  // Load configuration values on component mount
  useEffect(() => {
    const loadConfig = async () => {
      if (!configManager.getIsInitialized()) {
        await configManager.initialize();
      }

      setLlmProvider((configManager.get('general.llm_provider') as string) || 'openai');
      setOpenaiKey((configManager.get('general.openai.api_key') as string) || '');
      setOpenaiModel((configManager.get('general.openai.model') as string) || '');
      setOpenaiFlex((configManager.get('general.openai.flex') as boolean) ?? false);
      setGeminiKey((configManager.get('general.gemini.api_key') as string) || '');
      setGeminiModel((configManager.get('general.gemini.model') as string) || '');
      setClaudeKey((configManager.get('general.claude.api_key') as string) || '');
      setClaudeModel((configManager.get('general.claude.model') as string) || '');
      setCompatibleKey((configManager.get('general.openai_compatible.api_key') as string) || '');
      setCompatibleBaseUrl((configManager.get('general.openai_compatible.base_url') as string) || '');
      setCompatibleModel((configManager.get('general.openai_compatible.model') as string) || '');
      setSoundfontBaseUrl((configManager.get('general.soundfont.base_url') as string) || '');
    };

    loadConfig();
  }, [configManager]);

  // Debounced save function for text inputs
  const debouncedSave = useCallback((key: string, value: string) => {
    const timeoutId = setTimeout(async () => {
      try {
        await configManager.set(key, value);
        console.log(`Settings saved: ${key} = ${value}`);
      } catch (error) {
        console.error(`Failed to save setting ${key}:`, error);
      }
    }, 500); // 500ms debounce

    return () => clearTimeout(timeoutId);
  }, [configManager]);

  // Save configuration when values change
  const handleLlmProviderChange = async (value: string) => {
    setLlmProvider(value);
    try {
      await configManager.set('general.llm_provider', value);
      console.log('LLM provider changed to:', value);
    } catch (error) {
      console.error('Failed to save LLM provider:', error);
    }
  };

  const handleOpenaiKeyChange = (value: string) => {
    setOpenaiKey(value);
    debouncedSave('general.openai.api_key', value);
  };

  const handleOpenaiModelChange = (value: string) => {
    setOpenaiModel(value);
    debouncedSave('general.openai.model', value);
  };

  const handleOpenaiFlexChange = async (value: string) => {
    const boolValue = value === 'yes';
    setOpenaiFlex(boolValue);
    try {
      await configManager.set('general.openai.flex', boolValue);
      console.log('OpenAI Flex Mode changed to:', boolValue);
    } catch (error) {
      console.error('Failed to save OpenAI Flex Mode:', error);
    }
  };

  const handleGeminiKeyChange = (value: string) => {
    setGeminiKey(value);
    debouncedSave('general.gemini.api_key', value);
  };

  const handleGeminiModelChange = (value: string) => {
    setGeminiModel(value);
    debouncedSave('general.gemini.model', value);
  };

  const handleClaudeKeyChange = (value: string) => {
    setClaudeKey(value);
    debouncedSave('general.claude.api_key', value);
  };

  const handleClaudeModelChange = (value: string) => {
    setClaudeModel(value);
    debouncedSave('general.claude.model', value);
  };

  const handleCompatibleKeyChange = (value: string) => {
    setCompatibleKey(value);
    debouncedSave('general.openai_compatible.api_key', value);
  };

  const handleCompatibleBaseUrlChange = (value: string) => {
    setCompatibleBaseUrl(value);
    debouncedSave('general.openai_compatible.base_url', value);
  };

  const handleCompatibleModelChange = (value: string) => {
    setCompatibleModel(value);
    debouncedSave('general.openai_compatible.model', value);
  };

  const handleSoundfontBaseUrlChange = (value: string) => {
    setSoundfontBaseUrl(value);
    debouncedSave('general.soundfont.base_url', value);
  };

  // NOTE: Gemini and Claude are not supported yet due to CORS issues.
  return (
    <div className="settings-section">
      <div className="settings-section-header">
        <h3>General</h3>
      </div>
      
      <div className="settings-section-content">
        <div className="settings-group">
          <h4>LLM Provider</h4>
          
          <div className="settings-item">
            <label className="settings-label">
              LLM Provider
            </label>
            <select 
              className="settings-select" 
              value={llmProvider}
              onChange={(e) => handleLlmProviderChange(e.target.value)}
            >
              <option value="openai">OpenAI</option>
              {/* <option value="gemini">Gemini</option>
              <option value="claude">Claude</option> */}
              <option value="openai_compatible">OpenAI Compatible (e.g. OpenRouter, Ollama)</option>
            </select>
          </div>
        </div>

        <div className="settings-group">
          <h4>OpenAI</h4>
          
          <div className="settings-item">
            <label className="settings-label">
              Key
            </label>
            <input 
              type="password" 
              className="settings-input"
              placeholder="Enter your OpenAI API key"
              value={openaiKey}
              onChange={(e) => handleOpenaiKeyChange(e.target.value)}
            />
            <div className="settings-help" style={{ fontSize: '12px', color: '#888', marginTop: '4px' }}>
              {isLocalEnvironment
                ? 'Keys are persisted locally (the IndexedDB in your browser).'
                : 'For security, keys are not persisted on non-local hosts and are kept in-memory for this session.'}
            </div>
          </div>
          
          <div className="settings-item">
            <label className="settings-label">
              Model
            </label>
            <select
              className="settings-select"
              value={openaiModel}
              onChange={(e) => handleOpenaiModelChange(e.target.value)}
            >
              {/* <option value="gpt-5">gpt-5</option>
              <option value="gpt-5-mini">gpt-5-mini</option>
              <option value="gpt-5-nano">gpt-5-nano</option> */}
              <option value="gpt-4o">gpt-4o</option>
            </select>
          </div>

          <div className="settings-item">
            <label className="settings-label">
              Flex Mode
            </label>
            <select
              className="settings-select"
              value={openaiFlex ? 'yes' : 'no'}
              onChange={(e) => handleOpenaiFlexChange(e.target.value)}
            >
              <option value="no">No</option>
              <option value="yes">Yes</option>
            </select>
            <div className="settings-help" style={{ fontSize: '12px', color: '#888', marginTop: '4px' }}>
              Flex Mode uses OpenAI's flexible service tier. Pros: potential cost savings and higher throughput during busy periods. Cons: variable latency and possible queueing/deprioritization. Applies only to the OpenAI provider; no effect for OpenAI Compatible servers.
            </div>
          </div>
        </div>

        {/* <div className="settings-group">
          <h4>Gemini</h4>
          
          <div className="settings-item">
            <label className="settings-label">
              Key
            </label>
            <input 
              type="password" 
              className="settings-input"
              placeholder="Enter your Gemini API key"
              value={geminiKey}
              onChange={(e) => handleGeminiKeyChange(e.target.value)}
            />
          </div>
          
          <div className="settings-item">
            <label className="settings-label">
              Model
            </label>
            <input 
              type="text" 
              className="settings-input"
              placeholder="e.g. gemini-2.5-flash"
              value={geminiModel}
              onChange={(e) => handleGeminiModelChange(e.target.value)}
            />
          </div>
        </div>

        <div className="settings-group">
          <h4>Claude</h4>
          
          <div className="settings-item">
            <label className="settings-label">
              Key
            </label>
            <input 
              type="password" 
              className="settings-input"
              placeholder="Enter your Claude API key"
              value={claudeKey}
              onChange={(e) => handleClaudeKeyChange(e.target.value)}
            />
          </div>
          
          <div className="settings-item">
            <label className="settings-label">
              Model
            </label>
            <input 
              type="text" 
              className="settings-input"
              placeholder="e.g. claude-sonnet-4-0"
              value={claudeModel}
              onChange={(e) => handleClaudeModelChange(e.target.value)}
            />
          </div>
        </div> */}

        <div className="settings-group">
          <h4>OpenAI Compatible Server</h4>
          
          <div className="settings-item">
            <label className="settings-label">
              Key
            </label>
            <input 
              type="password" 
              className="settings-input"
              placeholder="Enter your API key"
              value={compatibleKey}
              onChange={(e) => handleCompatibleKeyChange(e.target.value)}
            />
            <div className="settings-help" style={{ fontSize: '12px', color: '#888', marginTop: '4px' }}>
              {isLocalEnvironment
                ? 'Keys are persisted locally (the IndexedDB in your browser).'
                : 'For security, keys are not persisted on non-local hosts and are kept in-memory for this session.'}
            </div>
          </div>
          
          <div className="settings-item">
            <label className="settings-label">
              Base URL
            </label>
            <input 
              type="text" 
              className="settings-input"
              placeholder="e.g. https://api.openrouter.ai/v1"
              value={compatibleBaseUrl}
              onChange={(e) => handleCompatibleBaseUrlChange(e.target.value)}
            />
          </div>
          
          <div className="settings-item">
            <label className="settings-label">
              Model
            </label>
            <input 
              type="text" 
              className="settings-input"
              placeholder="e.g. qwen3:30b"
              value={compatibleModel}
              onChange={(e) => handleCompatibleModelChange(e.target.value)}
            />
          </div>
        </div>

        <div className="settings-group">
          <h4>Soundfont Settings</h4>

          <div className="settings-item">
            <label className="settings-label">
              Base URL
            </label>
            <input
              type="text"
              className="settings-input"
              placeholder="e.g. https://cdn.jsdelivr.net/npm/soundfont-for-samplers/FluidR3_GM/"
              value={soundfontBaseUrl}
              onChange={(e) => handleSoundfontBaseUrlChange(e.target.value)}
            />
            <div className="settings-help" style={{ fontSize: '12px', color: '#888', marginTop: '4px' }}>
              Changing this URL to an incompatible soundfont source may cause some instruments to sound wrong or not play.
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default GeneralSettings;