import { useEffect, useState } from 'react'
import { Sparkles, Cpu, Search, Network, ListTree, Wrench, Braces, Radio, RefreshCw, ShieldCheck } from 'lucide-react'
import { getRagToggles, updateRagToggle, type RagToggles } from '../api/client'

/**
 * Mall AI 기법 토글 설정 화면 — 중앙 guardia-rag 기법을 운영자가 켜고 끈다.
 *
 * rerank·graphrag·hybrid(retrieval_mode)·tool_use·structured·stream on/off + 파라미터(top_k·agent step·temperature).
 * mall_setting(rag.* 네임스페이스) 격리 저장. 무거운 기법(graphrag·rerank·tool_use·stream)은 기본 off·옵트인.
 * 변경은 MANAGER+ (백엔드 SecurityConfig + @PreAuthorize 통제 — USER 가 PUT 시 403).
 */
export default function AiTechniques() {
  const [t, setT] = useState<RagToggles | null>(null)
  const [busy, setBusy] = useState('')
  const [err, setErr] = useState('')
  const role = localStorage.getItem('mall_role') || ''
  const canEdit = role === 'ADMIN' || role === 'MANAGER'

  const load = () => getRagToggles().then(setT).catch(() => setErr('Failed to load toggles'))
  useEffect(() => { load() }, [])

  const set = async (key: string, value: string | number | boolean) => {
    if (!canEdit) { setErr('No permission to change (MANAGER or above)'); return }
    setBusy(key); setErr('')
    try { const next = await updateRagToggle(key, value); setT(next) }
    catch { setErr('Change failed — check permission or server') }
    finally { setBusy('') }
  }

  if (!t) return <div className="text-slate-400 text-sm">Loading…</div>

  const Switch = ({ on, k, disabled }: { on: boolean; k: string; disabled?: boolean }) => (
    <button
      disabled={!canEdit || busy === k || disabled}
      onClick={() => set(k, !on)}
      className={`relative w-11 h-6 rounded-full transition ${on ? 'bg-brand' : 'bg-edge'} ${(!canEdit || disabled) ? 'opacity-50 cursor-not-allowed' : ''}`}
    >
      <span className={`absolute top-0.5 ${on ? 'left-6' : 'left-0.5'} w-5 h-5 rounded-full bg-white transition`} />
    </button>
  )

  const Row = ({ icon: Icon, title, desc, children }: any) => (
    <div className="flex items-start justify-between gap-4 py-3 border-b border-edge last:border-0">
      <div className="flex items-start gap-3">
        <Icon size={16} className="text-brand mt-0.5" />
        <div>
          <div className="text-sm font-medium">{title}</div>
          <div className="text-xs text-slate-400 mt-0.5">{desc}</div>
        </div>
      </div>
      <div className="shrink-0">{children}</div>
    </div>
  )

  return (
    <div>
      <div className="flex items-center justify-between mb-5">
        <h1 className="text-xl font-bold flex items-center gap-2"><Sparkles className="text-brand" size={20} /> AI Techniques</h1>
        <div className="flex items-center gap-2">
          <span className={`flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-full bg-card border border-edge ${t.ragAvailable ? 'text-emerald-400' : 'text-amber-400'}`}>
            <Cpu size={13} /> central guardia-rag {t.ragAvailable ? 'available' : 'unavailable (Mall fallback)'}
          </span>
          <button onClick={load} className="p-2 rounded-lg bg-card border border-edge text-slate-300"><RefreshCw size={14} /></button>
        </div>
      </div>

      {err && <div className="mb-3 text-xs text-rose-400 bg-rose-950/30 border border-rose-900/50 rounded-lg px-3 py-2">{err}</div>}
      {!canEdit && <div className="mb-3 text-xs text-slate-400">Read-only — changes require MANAGER role or above.</div>}

      <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
        {/* 마스터 + 검색 기법 — 상품 추천·자연어 검색 경로에 적용 */}
        <div className="bg-card border border-edge rounded-xl p-5">
          <h3 className="text-sm font-semibold mb-2">Retrieval &amp; Generation</h3>
          <Row icon={ShieldCheck} title="Use RAG layer" desc="off → all AI falls back to existing Ollama/Java path">
            <Switch on={t.ragEnabled} k="rag.enabled" />
          </Row>
          <Row icon={Search} title="Hybrid search (retrieval_mode)" desc="vector → hybrid (BM25+vector) for recommend/search">
            <select disabled={!canEdit || busy === 'rag.retrieval_mode'} value={t.retrievalMode}
              onChange={e => set('rag.retrieval_mode', e.target.value)}
              className="bg-ink border border-edge rounded-lg text-xs px-2 py-1.5 outline-none">
              <option value="vector">vector</option>
              <option value="hybrid">hybrid</option>
              <option value="graph">graph</option>
            </select>
          </Row>
          <Row icon={Network} title="GraphRAG" desc="knowledge-graph search. Heavy → off by default (on ⇒ mode=graph)">
            <Switch on={t.graphrag} k="rag.graphrag" />
          </Row>
          <Row icon={ListTree} title="Rerank" desc="cross-encoder reorder. Heavy → off by default">
            <Switch on={t.rerank} k="rag.rerank" />
          </Row>
        </div>

        {/* 에이전틱·구조화·스트리밍 — 수요예측/재고이양·결정론 결과·응답 스트리밍 */}
        <div className="bg-card border border-edge rounded-xl p-5">
          <h3 className="text-sm font-semibold mb-2">Agentic · Structured · Streaming</h3>
          <Row icon={Braces} title="Structured output" desc="recommend/decision results as /structured deterministic JSON. Default on">
            <Switch on={t.structured} k="rag.structured" />
          </Row>
          <Row icon={Wrench} title="Agentic tool-use (/agent)" desc="demand forecast / stock transfer via tool calls. Heavy → off by default">
            <Switch on={t.toolUse} k="rag.tool_use" />
          </Row>
          <Row icon={Radio} title="Token streaming (SSE)" desc="stream long answers (CS reply / card message). Default off">
            <Switch on={t.stream} k="rag.stream" />
          </Row>
        </div>

        {/* 파라미터 */}
        <div className="bg-card border border-edge rounded-xl p-5 lg:col-span-2">
          <h3 className="text-sm font-semibold mb-3">Parameters</h3>
          <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
            <Num label="top_k (1–20)" value={t.topK} min={1} max={20} step={1} onSave={v => set('rag.top_k', v)} canEdit={canEdit} />
            <Num label="agent step cap (1–8)" value={t.agentMaxSteps} min={1} max={8} step={1} onSave={v => set('rag.agent_max_steps', v)} canEdit={canEdit} />
            <Num label="faithfulness threshold (0–1)" value={t.faithfulnessThreshold} min={0} max={1} step={0.05} onSave={v => set('rag.faithfulness_threshold', v)} canEdit={canEdit} />
            <Num label="temperature (0–1)" value={t.temperature} min={0} max={1} step={0.05} onSave={v => set('rag.temperature', v)} canEdit={canEdit} />
          </div>
          <div className="mt-4 text-xs text-slate-400">
            Generation model: <span className="text-slate-200 font-mono">{t.generationModel}</span> · small model by default (server RAM). Heavy techniques are guarded by concurrency limits and fallback.
          </div>
        </div>
      </div>
    </div>
  )
}

function Num({ label, value, min, max, step, onSave, canEdit }:
  { label: string; value: number; min: number; max: number; step: number; onSave: (v: number) => void; canEdit: boolean }) {
  const [v, setV] = useState(String(value))
  useEffect(() => { setV(String(value)) }, [value])
  return (
    <div>
      <label className="block text-xs text-slate-400 mb-1">{label}</label>
      <input type="number" min={min} max={max} step={step} value={v} disabled={!canEdit}
        onChange={e => setV(e.target.value)}
        onBlur={() => { const n = Number(v); if (!Number.isNaN(n)) onSave(n) }}
        className="w-full bg-ink border border-edge rounded-lg text-sm px-3 py-2 outline-none focus:border-brand disabled:opacity-50" />
    </div>
  )
}
