// ─── Agent Settings Page ─────────────────────────────────────────────────────

const GEMINI_DEFAULT_MODEL = 'gemini-3.1-flash-live-preview';
const GEMINI_TTS_DEFAULT_MODEL = 'gemini-3.1-flash-tts-preview';
const GEMINI_LANGUAGE_OPTIONS = [
  { value: '', label: 'Auto-detect' },
  { value: 'en-IN', label: 'English (India)' },
  { value: 'hi-IN', label: 'Hindi' },
  { value: 'mr-IN', label: 'Marathi' },
  { value: 'ta-IN', label: 'Tamil' },
  { value: 'te-IN', label: 'Telugu' },
];

const CFG_DEFAULTS = {
  first_line: "Namaste! This is Aryan from SPX AI. We help businesses automate with AI. Hmm, may I ask what kind of business you run?",
  agent_instructions: "",
  stt_min_endpointing_delay: 0.15, max_endpointing_delay: 0.9,
  turn_detection_mode: 'stt', endpointing_mode: 'dynamic',
  allow_interruptions: true, interruption_mode: 'adaptive',
  discard_audio_if_uninterruptible: true, min_interruption_duration: 0.18,
  min_interruption_words: 0, resume_false_interruption: true,
  false_interruption_timeout: 1.2, preemptive_generation: true,
  preemptive_generation_enable_tts: false, preemptive_generation_max_speech_duration: 8.0,
  preemptive_generation_max_retries: 2, use_tts_aligned_transcript: true,
  user_away_timeout: 15.0, session_close_transcript_timeout: 2.0, max_turns: 25,
  voice_mode: 'pipeline', llm_provider: 'groq', llm_model: 'llama-3.3-70b-versatile',
  stt_provider: 'sarvam', stt_language: 'unknown', stt_model: 'saaras:v3', stt_mode: 'translate',
  stt_sample_rate: 16000, tts_provider: 'cartesia', tts_language: 'hi-IN',
  tts_voice: 'kavya', xai_tts_voice: 'eve', xai_tts_style_preset: 'spirited',
  cartesia_voice_id: '', cartesia_tts_model: 'sonic-3',
  sarvam_tts_model: 'bulbul:v3', cartesia_sample_rate: 24000, xai_tts_sample_rate: 24000,
  gemini_live_model: GEMINI_DEFAULT_MODEL, gemini_live_voice: 'Puck', gemini_live_temperature: 0.8, gemini_live_language: '', gemini_tts_model: GEMINI_TTS_DEFAULT_MODEL,
  lang_preset: 'multilingual',
  livekit_url: '', sip_trunk_id: '',
  livekit_api_key: '', livekit_api_secret: '',
  groq_api_key: '', openrouter_api_key: '',
  google_api_key: '', sarvam_api_key: '',
  cartesia_api_key: '', x_ai_api_key: '',
  supabase_url: '', supabase_key: '',
};

function GeneralTab({ cfg, set }) {
  return (
    <div style={{ display: 'grid', gap: 20 }}>
      <C.Input label="Opening Greeting" value={cfg.first_line || ''} onChange={set('first_line')} rows={3}
        hint="The first sentence your agent speaks when a prospect answers." />
      <C.Input label="System Prompt" value={cfg.agent_instructions || ''} onChange={set('agent_instructions')} rows={10} mono
        hint="Full instructions that shape agent personality, goals, and knowledge rules." />
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
        <C.Input label="Listening Sensitivity Delay (s)" type="number" value={cfg.stt_min_endpointing_delay ?? 0.15}
          onChange={v => set('stt_min_endpointing_delay')(parseFloat(v))} hint="Min endpointing delay before agent responds." />
        <C.Input label="Max Turns" type="number" value={cfg.max_turns ?? 25}
          onChange={v => set('max_turns')(parseInt(v))} hint="Maximum dialogue turns per session." />
      </div>
    </div>
  );
}

function TurnHandlingTab({ cfg, set }) {
  return (
    <div style={{ display: 'grid', gap: 20 }}>
      <C.SectionTitle>Turn Detection</C.SectionTitle>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
        <C.Select label="Turn Detection Mode" value={cfg.turn_detection_mode || 'stt'} onChange={set('turn_detection_mode')}
          options={['stt','vad','manual'].map(v => ({ value: v, label: v.toUpperCase() }))} />
        <C.Select label="Endpointing Mode" value={cfg.endpointing_mode || 'dynamic'} onChange={set('endpointing_mode')}
          options={['dynamic','fixed'].map(v => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) }))} />
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
        <C.Input label="Max Endpointing Delay (s)" type="number" value={cfg.max_endpointing_delay ?? 0.9}
          onChange={v => set('max_endpointing_delay')(parseFloat(v))} />
        <C.Select label="Interruption Mode" value={cfg.interruption_mode || 'adaptive'} onChange={set('interruption_mode')}
          options={['adaptive','vad'].map(v => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) }))} />
      </div>
      <C.SectionTitle>Session</C.SectionTitle>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
        <C.Input label="Max Turns" type="number" value={cfg.max_turns ?? 25} onChange={v => set('max_turns')(parseInt(v))} />
        <C.Input label="User Away Timeout (s)" type="number" value={cfg.user_away_timeout ?? 15} onChange={v => set('user_away_timeout')(parseFloat(v))} />
      </div>
    </div>
  );
}

function LatencyTab({ cfg, set }) {
  return (
    <div style={{ display: 'grid', gap: 2 }}>
      <C.SectionTitle>Latency Toggles</C.SectionTitle>
      <C.Card style={{ padding: '8px 16px' }}>
        <C.Toggle label="Allow Interruptions" checked={!!cfg.allow_interruptions} onChange={set('allow_interruptions')}
          hint="Let the user interrupt the agent mid-speech." />
        <C.Toggle label="Resume After False Interruptions" checked={!!cfg.resume_false_interruption} onChange={set('resume_false_interruption')}
          hint="Continue speaking after detecting a false interrupt signal." />
        <C.Toggle label="Pre-generate TTS & Discard if Interrupted" checked={!!cfg.discard_audio_if_uninterruptible} onChange={set('discard_audio_if_uninterruptible')}
          hint="Pre-generate audio and discard if the user interrupts." />
        <C.Toggle label="Enable Preemptive Generation" checked={!!cfg.preemptive_generation} onChange={set('preemptive_generation')}
          hint="Start generating next response before user finishes speaking." />
        <C.Toggle label="Enable Preemptive TTS" checked={!!cfg.preemptive_generation_enable_tts} onChange={set('preemptive_generation_enable_tts')}
          hint="Also synthesise TTS during preemptive generation phase." />
        <C.Toggle label="Use TTS-Aligned Transcript" checked={!!cfg.use_tts_aligned_transcript} onChange={set('use_tts_aligned_transcript')}
          hint="Align transcript timing to TTS audio for accurate logs." />
      </C.Card>
      <C.SectionTitle>Timing Thresholds</C.SectionTitle>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 14 }}>
        <C.Input label="Min Interruption Duration (s)" type="number" value={cfg.min_interruption_duration ?? 0.18} onChange={v => set('min_interruption_duration')(parseFloat(v))} />
        <C.Input label="False Interruption Timeout (s)" type="number" value={cfg.false_interruption_timeout ?? 1.2} onChange={v => set('false_interruption_timeout')(parseFloat(v))} />
        <C.Input label="Preemptive Max Retries" type="number" value={cfg.preemptive_generation_max_retries ?? 2} onChange={v => set('preemptive_generation_max_retries')(parseInt(v))} />
        <C.Input label="Session Close Transcript Timeout (s)" type="number" value={cfg.session_close_transcript_timeout ?? 2} onChange={v => set('session_close_transcript_timeout')(parseFloat(v))} />
        <C.Input label="Min Interruption Words" type="number" value={cfg.min_interruption_words ?? 0} onChange={v => set('min_interruption_words')(parseInt(v))} />
        <C.Input label="Preemptive Max Speech Duration (s)" type="number" value={cfg.preemptive_generation_max_speech_duration ?? 8} onChange={v => set('preemptive_generation_max_speech_duration')(parseFloat(v))} />
        <C.Input label="User Away Timeout (s)" type="number" value={cfg.user_away_timeout ?? 15} onChange={v => set('user_away_timeout')(parseFloat(v))} />
      </div>
    </div>
  );
}

function ModelsTab({ cfg, set }) {
  const vm = cfg.voice_mode || 'pipeline';
  const geminiModel = cfg.gemini_live_model || GEMINI_DEFAULT_MODEL;
  const geminiLimited = /3\.1/i.test(geminiModel);
  return (
    <div style={{ display: 'grid', gap: 20 }}>
      <C.SectionTitle>Conversation Mode</C.SectionTitle>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 10 }}>
        {[
          { value: 'pipeline',    label: 'Pipeline',     sub: 'STT → LLM → TTS' },
          { value: 'gemini_live', label: 'Gemini Live',  sub: 'Google native audio' },
        ].map(m => (
          <div key={m.value} onClick={() => set('voice_mode')(m.value)}
            style={{ border: `1px solid ${vm === m.value ? '#5a7ef5' : 'rgba(255,255,255,0.08)'}`, borderRadius: 10, padding: '12px 14px', cursor: 'pointer', background: vm === m.value ? 'rgba(90,126,245,0.08)' : 'transparent', transition: 'all 0.15s' }}>
            <div style={{ fontSize: 13, fontWeight: 700, color: vm === m.value ? '#5a7ef5' : '#e8eaef' }}>{m.label}</div>
            <div style={{ fontSize: 11, color: '#7b849a', marginTop: 3 }}>{m.sub}</div>
          </div>
        ))}
      </div>

      {vm === 'pipeline' && <>
        <C.SectionTitle>LLM Provider</C.SectionTitle>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
          <C.Select label="Provider" value={cfg.llm_provider || 'groq'} onChange={set('llm_provider')}
            options={[{value:'openrouter',label:'OpenRouter'},{value:'groq',label:'Groq'},{value:'sarvam',label:'Sarvam'}]} />
          <C.Input label="Model ID" value={cfg.llm_model || ''} onChange={set('llm_model')} placeholder="e.g. google/gemini-2.5-flash-lite" mono />
        </div>

        <C.SectionTitle>Speech-to-Text (STT)</C.SectionTitle>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 14 }}>
          <C.Select label="STT Provider" value={cfg.stt_provider || 'sarvam'} onChange={set('stt_provider')}
            options={[{value:'sarvam',label:'Sarvam'},{value:'xai',label:'xAI'}]} />
          <C.Input label="Model" value={cfg.stt_model || ''} onChange={set('stt_model')} mono />
          <C.Select label="Mode" value={cfg.stt_mode || 'translate'} onChange={set('stt_mode')}
            options={[{value:'translate',label:'Translate'},{value:'transcribe',label:'Transcribe'}]} />
          <C.Select label="Recognition Language" value={cfg.stt_language || 'unknown'} onChange={set('stt_language')}
            options={['unknown','en-IN','hi-IN','mr-IN','ta-IN','te-IN','gu-IN','bn-IN','kn-IN','ml-IN'].map(v => ({ value: v, label: v }))} />
          <C.Input label="Sample Rate (Hz)" type="number" value={cfg.stt_sample_rate ?? 16000} onChange={v => set('stt_sample_rate')(parseInt(v))} />
        </div>

        <C.SectionTitle>Text-to-Speech (TTS)</C.SectionTitle>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 14 }}>
          <C.Select label="TTS Provider" value={cfg.tts_provider || 'cartesia'} onChange={set('tts_provider')}
            options={[{value:'xai',label:'xAI'},{value:'cartesia',label:'Cartesia'},{value:'sarvam',label:'Sarvam'}]} />
          {cfg.tts_provider === 'xai' && <>
            <C.Input label="Voice" value={cfg.xai_tts_voice || 'eve'} onChange={set('xai_tts_voice')} placeholder="eve" />
            <C.Select label="Style Preset" value={cfg.xai_tts_style_preset || 'spirited'} onChange={set('xai_tts_style_preset')}
              options={['balanced','spirited','expressive'].map(v => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) }))} />
            <C.Input label="Sample Rate (Hz)" type="number" value={cfg.xai_tts_sample_rate ?? 24000} onChange={v => set('xai_tts_sample_rate')(parseInt(v))} />
          </>}
          {cfg.tts_provider === 'cartesia' && <>
            <C.Input label="Voice ID" value={cfg.cartesia_voice_id || ''} onChange={set('cartesia_voice_id')} mono />
            <C.Input label="Model" value={cfg.cartesia_tts_model || 'sonic-3'} onChange={set('cartesia_tts_model')} />
            <C.Input label="Sample Rate (Hz)" type="number" value={cfg.cartesia_sample_rate ?? 24000} onChange={v => set('cartesia_sample_rate')(parseInt(v))} />
          </>}
          {cfg.tts_provider === 'sarvam' && <>
            <C.Input label="Voice" value={cfg.tts_voice || 'kavya'} onChange={set('tts_voice')} placeholder="kavya" />
            <C.Select label="Model" value={cfg.sarvam_tts_model || 'bulbul:v3'} onChange={set('sarvam_tts_model')}
              options={['bulbul:v3','bulbul:v2'].map(v => ({ value: v, label: v }))} />
            <C.Select label="Language" value={cfg.tts_language || 'hi-IN'} onChange={set('tts_language')}
              options={['hi-IN','en-IN','mr-IN','ta-IN','te-IN','gu-IN','bn-IN','kn-IN','ml-IN'].map(v => ({ value: v, label: v }))} />
          </>}
        </div>
      </>}

      {vm === 'gemini_live' && <>
        <C.SectionTitle>Gemini Live Settings</C.SectionTitle>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
          <C.Input
            label="Model"
            value={geminiModel}
            onChange={set('gemini_live_model')}
            placeholder={GEMINI_DEFAULT_MODEL}
            hint="Default: Gemini 3.1 preview. Fixed greetings and wrap-ups use Gemini TTS with the same selected voice."
            mono
          />
          <C.Input label="Voice" value={cfg.gemini_live_voice || 'Puck'} onChange={set('gemini_live_voice')} />
          <C.Select
            label="Language"
            value={cfg.gemini_live_language ?? ''}
            onChange={set('gemini_live_language')}
            options={GEMINI_LANGUAGE_OPTIONS}
            hint="Leave on Auto-detect for multilingual campaigns."
          />
          <C.Input
            label="Scripted TTS Model"
            value={cfg.gemini_tts_model || GEMINI_TTS_DEFAULT_MODEL}
            onChange={set('gemini_tts_model')}
            placeholder={GEMINI_TTS_DEFAULT_MODEL}
            hint="Used only for fixed greetings and wrap-ups, with the same Gemini voice above."
            mono
          />
          <C.Input label="Temperature" type="number" value={cfg.gemini_live_temperature ?? 0.8} onChange={v => set('gemini_live_temperature')(parseFloat(v))} />
          {geminiLimited && (
            <div style={{ gridColumn: '1 / -1', background: 'rgba(251,191,36,0.12)', border: '1px solid rgba(251,191,36,0.24)', borderRadius: 10, padding: '12px 14px', color: '#fbbf24', fontSize: 12, lineHeight: 1.5 }}>
              Gemini 3.1 preview has limited LiveKit scripted-speech support. This app uses Gemini TTS with the same selected voice for fixed greetings and wrap-ups.
            </div>
          )}
        </div>
      </>}
    </div>
  );
}

function CredentialsTab({ cfg, set }) {
  const [show, setShow] = React.useState({});
  const toggleShow = k => setShow(p => ({ ...p, [k]: !p[k] }));
  const SecretInput = ({ label, k, hint }) => (
    <div style={{ display: 'grid', gap: 5 }}>
      <label style={{ fontSize: 12, fontWeight: 600, color: '#7b849a', letterSpacing: '0.04em', textTransform: 'uppercase' }}>{label}</label>
      <div style={{ display: 'flex', gap: 6 }}>
        <input type={show[k] ? 'text' : 'password'} value={cfg[k] || ''} onChange={e => set(k)(e.target.value)}
          style={{ flex: 1, background: '#1a1e28', border: '1px solid rgba(255,255,255,0.08)', borderRadius: 8, color: '#e8eaef', fontSize: 13, padding: '9px 12px', fontFamily: 'monospace', outline: 'none' }} />
        <button onClick={() => toggleShow(k)} style={{ background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.08)', borderRadius: 8, color: '#7b849a', cursor: 'pointer', padding: '0 12px', fontSize: 12 }}>
          {show[k] ? 'Hide' : 'Show'}
        </button>
      </div>
      {hint && <span style={{ fontSize: 11, color: '#5a6375' }}>{hint}</span>}
    </div>
  );
  return (
    <div style={{ display: 'grid', gap: 20 }}>
      <C.SectionTitle>LiveKit</C.SectionTitle>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
        <C.Input label="LiveKit URL" value={cfg.livekit_url || ''} onChange={set('livekit_url')} mono placeholder="wss://…" />
        <C.Input label="SIP Trunk ID" value={cfg.sip_trunk_id || ''} onChange={set('sip_trunk_id')} mono />
        <SecretInput label="API Key" k="livekit_api_key" />
        <SecretInput label="API Secret" k="livekit_api_secret" />
      </div>
      <C.SectionTitle>AI Provider Secrets</C.SectionTitle>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
        <SecretInput label="Groq API Key" k="groq_api_key" />
        <SecretInput label="OpenRouter API Key" k="openrouter_api_key" />
        <SecretInput label="Google API Key" k="google_api_key" />
        <SecretInput label="xAI API Key" k="x_ai_api_key" />
        <SecretInput label="Sarvam API Key" k="sarvam_api_key" />
        <SecretInput label="Cartesia API Key" k="cartesia_api_key" />
      </div>
      <C.SectionTitle>Supabase</C.SectionTitle>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
        <C.Input label="Supabase URL" value={cfg.supabase_url || ''} onChange={set('supabase_url')} mono />
        <SecretInput label="Supabase Key" k="supabase_key" />
      </div>
    </div>
  );
}

function AgentSettingsPage() {
  const [tab, setTab] = React.useState('General');
  const [cfg, setCfg] = React.useState({ ...CFG_DEFAULTS });
  const [loading, setLoading] = React.useState(true);
  const [saveState, setSaveState] = React.useState('idle'); // idle | saving | saved | error
  const tabs = ['General', 'Turn Handling', 'Latency', 'Models & Voice', 'API Credentials'];
  const set = k => v => setCfg(p => ({ ...p, [k]: v }));

  React.useEffect(() => {
    fetch('/api/config')
      .then(r => r.json())
      .then(data => { setCfg(p => ({ ...p, ...data })); setLoading(false); })
      .catch(() => setLoading(false));
  }, []);

  const handleSave = async () => {
    setSaveState('saving');
    try {
      const res = await fetch('/api/config', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(cfg),
      });
      if (!res.ok) throw new Error('Save failed');
      setSaveState('saved');
      setTimeout(() => setSaveState('idle'), 2500);
    } catch {
      setSaveState('error');
      setTimeout(() => setSaveState('idle'), 3000);
    }
  };

  const saveLabel = { idle: 'Save Changes', saving: 'Saving…', saved: '✓ Saved', error: '✗ Error' }[saveState];
  const saveVariant = saveState === 'saved' ? 'success' : saveState === 'error' ? 'danger' : 'primary';

  return (
    <div>
      <C.PageHeader title="Agent Settings"
        sub="Configure your voice agent's behaviour, models, and credentials"
        action={<C.Btn variant={saveVariant} onClick={handleSave} disabled={saveState === 'saving'}>{saveLabel}</C.Btn>} />
      <div style={{ marginBottom: 24 }}>
        <C.Tabs tabs={tabs} active={tab} onChange={setTab} />
      </div>
      {loading ? <C.Spinner /> : (
        <C.Card style={{ padding: 24 }}>
          {tab === 'General'         && <GeneralTab cfg={cfg} set={set} />}
          {tab === 'Turn Handling'   && <TurnHandlingTab cfg={cfg} set={set} />}
          {tab === 'Latency'         && <LatencyTab cfg={cfg} set={set} />}
          {tab === 'Models & Voice'  && <ModelsTab cfg={cfg} set={set} />}
          {tab === 'API Credentials' && <CredentialsTab cfg={cfg} set={set} />}
        </C.Card>
      )}
    </div>
  );
}

Object.assign(window, { AgentSettingsPage });
