/*
 *  StreamTestView.tsx
 *  Zyquo Cloud Web
 *
 *  Author: Simon-Pierre Boucher
 *  Mail: contact@spboucher.ai
 *
 *  Phase 2 gate: a bare test view that renders a REAL streaming completion
 *  token-by-token against any configured provider, using a key from
 *  localStorage. Reached via #stream-test. Superseded by the real chat UI in
 *  Phase 4 but kept for verification (Phase 7 drives it programmatically).
 */

import { useRef, useState } from 'react'
import { cheapestModel, findModel, modelsFor } from '../providers/catalog'
import { clientFor } from '../providers/registry'
import { ProviderError } from '../providers/types'
import { getKey, configuredProviders } from '../storage/keys'
import { BUILT_IN_PROVIDERS, type Provider } from '../types'

export default function StreamTestView() {
  const [provider, setProvider] = useState<Provider>('openai')
  const [modelID, setModelID] = useState('')
  const [prompt, setPrompt] = useState('Count from 1 to 10, one number per line.')
  const [output, setOutput] = useState('')
  const [reasoning, setReasoning] = useState('')
  const [status, setStatus] = useState('idle')
  const [tokens, setTokens] = useState('')
  const abortRef = useRef<AbortController | null>(null)

  const run = async () => {
    const key = getKey(provider)
    if (!key) {
      setStatus(`no key for ${provider} in localStorage`)
      return
    }
    const model =
      (modelID !== '' ? findModel(provider, modelID) : undefined) ??
      cheapestModel(provider) ??
      modelsFor(provider)[0]
    if (!model) {
      setStatus('no model')
      return
    }
    setOutput('')
    setReasoning('')
    setTokens('')
    setStatus(`streaming ${model.id}…`)
    const controller = new AbortController()
    abortRef.current = controller
    try {
      const client = clientFor(model)
      const events = client.streamChat(
        {
          model,
          messages: [
            {
              id: 't1',
              role: 'user',
              text: prompt,
              createdAt: Date.now(),
            },
          ],
          parameters: { maxTokens: 256 },
          stream: true,
        },
        key,
        controller.signal
      )
      for await (const event of events) {
        if (event.type === 'textDelta') setOutput((prev) => prev + event.text)
        else if (event.type === 'reasoningDelta') setReasoning((prev) => prev + event.text)
        else if (event.type === 'usage')
          setTokens(`${event.usage.inputTokens}→${event.usage.outputTokens} tok`)
        else if (event.type === 'finished') setStatus(`finished (${event.reason ?? 'n/a'})`)
      }
    } catch (err) {
      setStatus(err instanceof ProviderError ? `${err.kind}: ${err.message}` : String(err))
    } finally {
      abortRef.current = null
    }
  }

  return (
    <div
      style={{
        padding: 'var(--z-space-xl)',
        maxWidth: 720,
        margin: '0 auto',
        height: '100%',
        overflow: 'auto',
        fontFamily: 'var(--z-font-mono)',
        fontSize: 12.5,
      }}
    >
      <h2 style={{ fontFamily: 'var(--z-font-sans)' }}>Zyquo Cloud Web — stream test</h2>
      <p data-testid="configured">configured: {configuredProviders().join(', ') || '(none)'}</p>
      <div style={{ display: 'flex', gap: 8, marginBottom: 12, flexWrap: 'wrap' }}>
        <select
          data-testid="provider"
          value={provider}
          onChange={(e) => setProvider(e.target.value as Provider)}
        >
          {BUILT_IN_PROVIDERS.map((p) => (
            <option key={p} value={p}>
              {p}
            </option>
          ))}
        </select>
        <input
          data-testid="model"
          placeholder="model id (blank = cheapest)"
          value={modelID}
          onChange={(e) => setModelID(e.target.value)}
          style={{ width: 260 }}
        />
        <input
          data-testid="prompt"
          value={prompt}
          onChange={(e) => setPrompt(e.target.value)}
          style={{ width: 320 }}
        />
        <button data-testid="run" onClick={() => void run()}>
          Stream
        </button>
        <button data-testid="stop" onClick={() => abortRef.current?.abort()}>
          Stop
        </button>
      </div>
      <p data-testid="status">status: {status}</p>
      <p data-testid="tokens">{tokens}</p>
      {reasoning !== '' && (
        <pre
          data-testid="reasoning"
          style={{ whiteSpace: 'pre-wrap', color: 'var(--z-text-tertiary)' }}
        >
          {reasoning}
        </pre>
      )}
      <pre data-testid="output" style={{ whiteSpace: 'pre-wrap' }}>
        {output}
      </pre>
    </div>
  )
}
