import { useEffect, useState } from 'react'
import { Cpu, Save, Play, Sparkles, ShieldCheck } from 'lucide-react'
import { getRagToggles, updateRagToggle, ragContentDraft, ragModerate } from '../api/client'
import { hasRole, currentRole } from '../components/rbac'

/**
 * CMS 최신 AI 기법(중앙 guardia-rag) 토글 설정 + 라이브 적용 테스트.
 *
 * - 토글: hybrid/graphrag(검색)·rerank·tool_use(에이전틱)·structured(결정론)·stream + 파라미터(top_k·step 상한·신뢰도·온도·모델)
 * - 무거운 기법(graphrag·rerank·tool_use)은 기본 off (서버 RAM 제약)
 * - 적용 metadata(applied)·degraded 를 응답에 표기 → 토글 effect 관측
 * - 외부 API 0 (중앙 guardia-rag = 온프레미스). 미가용 시 CMS 로컬 폴백(degraded:true)
 */
interface Toggles {
  ragEnabled: boolean
  retrievalMode: string
  rerank: boolean
  graphrag: boolean
  toolUse: boolean
  stream: boolean
  topK: number
  stepLimit: number
  faithfulnessThreshold: number
  temperature: number
  generationModel: string
  ragAvailable?: boolean
}

const BOOL_KEYS: { key: string; label: string; hint: string; heavy?: boolean }[] = [
  { key: 'rag.enabled', label: 'RAG 경유 (마스터)', hint: 'off 시 모든 AI 호출이 CMS 로컬 폴백' },
  { key: 'rag.rerank', label: '리랭킹 (rerank)', hint: 'cross-encoder 재정렬 — 정확도↑·RAM↑', heavy: true },
  { key: 'rag.graphrag', label: 'GraphRAG (graph)', hint: '지식그래프 검색 — 관계 추론·RAM↑', heavy: true },
  { key: 'rag.tool_use', label: '에이전틱 tool-use', hint: '다단계 콘텐츠 작업(/agent) — 옵트인·RAM↑', heavy: true },
  { key: 'rag.stream', label: 'SSE 스트리밍', hint: '긴 초안 토큰 스트리밍' },
]

export default function AiTechniques() {
  const [t, setT] = useState<Toggles | null>(null)
  const [msg, setMsg] = useState('')
  const [err, setErr] = useState('')
  const [draftRes, setDraftRes] = useState<any>(null)
  const [modRes, setModRes] = useState<any>(null)
  const [topic, setTopic] = useState('봄맞이 신상 화분')
  const [ugc, setUgc] = useState('이 상품 정말 최고예요! 강추합니다')
  const [busy, setBusy] = useState('')
  const editable = hasRole('EDITOR', currentRole())

  const load = () =>
    getRagToggles()
      .then((d: Toggles) => { setT(d); setErr('') })
      .catch(() => setErr('AI 기법 토글을 불러오지 못했습니다.'))
  useEffect(() => { load() }, [])

  const save = async (key: string, value: string) => {
    setMsg(''); setErr('')
    try { const d = await updateRagToggle(key, value); setT(d); setMsg(`'${key}' 저장됨`) }
    catch (e: any) { setErr(e?.response?.status === 403 ? '권한이 없습니다 (Editor+).' : '저장 실패') }
  }

  const runDraft = async () => {
    setBusy('draft'); setDraftRes(null)
    try { setDraftRes(await ragContentDraft('product', topic, '친근함')) }
    catch { setDraftRes({ error: '호출 실패' }) } finally { setBusy('') }
  }
  const runMod = async () => {
    setBusy('mod'); setModRes(null)
    try { setModRes(await ragModerate(ugc)) }
    catch { setModRes({ error: '호출 실패' }) } finally { setBusy('') }
  }

  if (!t) return <div className="text-slate-500">{err || '불러오는 중...'}</div>

  const Badge = ({ on, label }: { on: boolean; label: string }) => (
    <span className={`px-2 py-0.5 rounded text-[11px] font-medium ${on ? 'bg-brand/15 text-brand' : 'bg-slate-500/15 text-slate-400'}`}>{label}</span>
  )

  return (
    <div>
      <div className="flex items-center justify-between mb-6">
        <h1 className="text-xl font-bold flex items-center gap-2"><Cpu className="text-brand" size={20} /> AI 기법 (중앙 guardia-rag)</h1>
        <span className={`px-2.5 py-1 rounded-lg text-xs font-medium ${t.ragAvailable ? 'bg-emerald-500/15 text-emerald-300' : 'bg-amber-500/15 text-amber-300'}`}>
          중앙 RAG {t.ragAvailable ? '가용' : '미가용 (로컬 폴백)'}
        </span>
      </div>

      {msg && <div className="bg-brand/10 border border-brand/30 text-brand text-sm rounded-lg px-4 py-2.5 mb-4">{msg}</div>}
      {err && <div className="bg-rose-500/10 border border-rose-500/40 text-rose-300 text-sm rounded-lg px-4 py-2.5 mb-4">{err}</div>}
      {!editable && <div className="bg-amber-500/10 border border-amber-500/30 text-amber-300 text-sm rounded-lg px-4 py-2.5 mb-4">조회 전용입니다. 토글 변경은 Editor+ 권한이 필요합니다.</div>}

      <div className="grid grid-cols-1 lg:grid-cols-2 gap-5">
        {/* 토글 설정 */}
        <div className="bg-card border border-edge rounded-xl p-5">
          <h2 className="font-semibold mb-3 flex items-center gap-2"><ShieldCheck size={16} className="text-brand" /> 기법 토글</h2>

          {/* retrieval_mode */}
          <div className="flex items-center justify-between py-2.5 border-b border-edge/50">
            <div><div className="text-sm font-medium">검색 모드 (retrieval_mode)</div><div className="text-[11px] text-slate-500">vector(경량 기본) · hybrid(BM25+벡터) · graph</div></div>
            <select className="inp w-32" value={t.retrievalMode} disabled={!editable}
              onChange={e => save('rag.retrieval_mode', e.target.value)}>
              <option value="vector">vector</option><option value="hybrid">hybrid</option><option value="graph">graph</option>
            </select>
          </div>

          {BOOL_KEYS.map(b => {
            const cur = (t as any)[b.key.replace('rag.', '').replace(/_(\w)/g, (_, c) => c.toUpperCase())] as boolean
            return (
              <div key={b.key} className="flex items-center justify-between py-2.5 border-b border-edge/50">
                <div>
                  <div className="text-sm font-medium flex items-center gap-1.5">{b.label}{b.heavy && <span className="text-[10px] text-amber-400">RAM↑ 기본 off</span>}</div>
                  <div className="text-[11px] text-slate-500">{b.hint}</div>
                </div>
                <button disabled={!editable} onClick={() => save(b.key, String(!cur))}
                  className={`w-11 h-6 rounded-full transition-colors relative ${cur ? 'bg-brand' : 'bg-slate-600'} ${!editable ? 'opacity-50' : ''}`}>
                  <span className={`absolute top-0.5 w-5 h-5 rounded-full bg-white transition-all ${cur ? 'left-[22px]' : 'left-0.5'}`} />
                </button>
              </div>
            )
          })}

          {/* 숫자 파라미터 */}
          {[
            { key: 'rag.top_k', label: 'top_k (검색 결과 수)', val: t.topK, min: 1, max: 20 },
            { key: 'rag.step_limit', label: 'step 상한 (/agent)', val: t.stepLimit, min: 1, max: 8 },
            { key: 'rag.faithfulness_threshold', label: '신뢰도 임계값', val: t.faithfulnessThreshold, min: 0, max: 1, step: 0.05 },
            { key: 'rag.temperature', label: 'temperature', val: t.temperature, min: 0, max: 1, step: 0.05 },
          ].map(p => (
            <div key={p.key} className="flex items-center justify-between py-2.5 border-b border-edge/50">
              <div className="text-sm">{p.label}</div>
              <input type="number" className="inp w-24" defaultValue={p.val} min={p.min} max={p.max} step={(p as any).step || 1} disabled={!editable}
                onBlur={e => save(p.key, e.target.value)} />
            </div>
          ))}
          <div className="flex items-center justify-between py-2.5">
            <div className="text-sm">생성 모델</div>
            <input className="inp w-40" defaultValue={t.generationModel} disabled={!editable}
              onBlur={e => save('rag.generation_model', e.target.value)} />
          </div>
          <p className="text-[11px] text-slate-500 mt-2">설정은 cms_setting(rag.*)에 격리 저장 · 변경 시 감사로그 기록 · 무거운 기법 기본 off</p>
        </div>

        {/* 라이브 적용 테스트 */}
        <div className="space-y-5">
          <div className="bg-card border border-edge rounded-xl p-5">
            <h2 className="font-semibold mb-3 flex items-center gap-2"><Sparkles size={16} className="text-brand" /> 콘텐츠 초안 (/rag/answer · /agent)</h2>
            <input className="inp w-full mb-2" value={topic} onChange={e => setTopic(e.target.value)} placeholder="주제" />
            <button onClick={runDraft} disabled={busy === 'draft'} className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-brand text-ink text-xs font-semibold">
              <Play size={13} /> {busy === 'draft' ? '생성 중...' : '초안 생성'}
            </button>
            {draftRes && (
              <div className="mt-3 text-sm">
                <div className="bg-panel rounded-lg p-3 whitespace-pre-wrap text-slate-200">{String(draftRes.draft ?? draftRes.error ?? '')}</div>
                <div className="flex flex-wrap gap-1.5 mt-2">
                  <Badge on={!draftRes.degraded} label={draftRes.degraded ? `폴백(${draftRes.degraded_reason || 'degraded'})` : `엔진:${draftRes.engine || 'RAG'}`} />
                  {draftRes.applied && <>
                    <Badge on label={`mode:${draftRes.applied.retrievalMode}`} />
                    <Badge on={draftRes.applied.rerank} label="rerank" />
                    <Badge on={draftRes.applied.graphrag} label="graph" />
                    <Badge on={draftRes.applied.toolUse} label="tool-use" />
                  </>}
                  {draftRes.abstained && <Badge on={false} label="근거부족 보류" />}
                </div>
              </div>
            )}
          </div>

          <div className="bg-card border border-edge rounded-xl p-5">
            <h2 className="font-semibold mb-3 flex items-center gap-2"><ShieldCheck size={16} className="text-brand" /> UGC 모더레이션 (/rag/structured)</h2>
            <textarea className="inp w-full mb-2 h-16" value={ugc} onChange={e => setUgc(e.target.value)} placeholder="리뷰/댓글" />
            <button onClick={runMod} disabled={busy === 'mod'} className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-brand text-ink text-xs font-semibold">
              <Play size={13} /> {busy === 'mod' ? '판정 중...' : '판정'}
            </button>
            {modRes && (
              <div className="mt-3 text-sm flex flex-wrap gap-1.5 items-center">
                <span className={`px-2 py-0.5 rounded text-xs font-semibold ${modRes.verdict === 'APPROVE' ? 'bg-emerald-500/15 text-emerald-300' : modRes.verdict === 'REJECT' ? 'bg-rose-500/15 text-rose-300' : 'bg-amber-500/15 text-amber-300'}`}>
                  {modRes.verdict || modRes.error}
                </span>
                {modRes.score != null && <Badge on label={`score:${modRes.score}`} />}
                {modRes.piiFlag && <Badge on={false} label="PII 감지" />}
                <Badge on={!modRes.degraded} label={modRes.degraded ? `폴백(${modRes.degraded_reason || 'rule'})` : '결정론 JSON'} />
              </div>
            )}
            <p className="text-[11px] text-slate-500 mt-2">애매(저신뢰) 시 자동 통과 금지 → REVIEW(보류). 사람 검토 큐로.</p>
          </div>
        </div>
      </div>
    </div>
  )
}
