import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import {
  Sparkles, AlertTriangle, TrendingUp, Wrench, LineChart, Search, Boxes, CalendarClock,
  Cpu, ThumbsUp, ThumbsDown, Quote,
} from 'lucide-react'
import { Card, Btn, Field } from '../components/ui'
import {
  getAiStatus, aiDefectRootCause, aiForecast, aiPredictiveMaintenance,
  aiSpcAnomaly, aiParseQuery, aiSafetyStock, aiScheduleOptimize,
  ragDefectAnalysis, ragPredictAnalysis, ragFeedback, postAiFeedback,
} from '../api/client'

/** 적용된 기법 배지 — 응답의 applied metadata 를 시각화(토글 effect 관측). */
function AppliedBadge({ data }: { data: any }) {
  const a = data?.applied
  if (!a) return null
  const chips: string[] = [`mode:${a.retrievalMode}`, `기법:${a.technique}`]
  if (a.rerank) chips.push('rerank')
  if (a.graphrag) chips.push('graphrag')
  if (a.hybrid) chips.push('hybrid')
  if (a.toolUse) chips.push(`agent(${a.maxSteps})`)
  if (a.structured) chips.push('structured')
  if (a.stream) chips.push('stream')
  if (data?.degraded) chips.push('⚠ degraded(폴백)')
  return (
    <div className="mt-2 flex flex-wrap gap-1">
      {chips.map((c, i) => (
        <span key={i} className={`text-[10px] px-1.5 py-0.5 rounded border ${c.startsWith('⚠') ? 'bg-amber-500/15 text-amber-300 border-amber-500/30' : 'bg-brand/10 text-brand border-brand/30'}`}>{c}</span>
      ))}
    </div>
  )
}

/** 👍/👎 피드백 (중앙 /rag/feedback, solution=mes 격리). answerId 가 있을 때만 노출. */
function FeedbackBar({ answerId, query }: { answerId?: string; query?: string }) {
  const [done, setDone] = useState('')
  if (!answerId) return null
  const send = async (verdict: 'up' | 'down') => {
    try { await ragFeedback({ answerId, query, verdict }); setDone(verdict === 'up' ? '👍 반영됨' : '👎 반영됨') } catch { setDone('전송 실패') }
  }
  return (
    <div className="mt-2 flex items-center gap-2 text-xs text-slate-400">
      <span>이 답변이 도움이 됐나요?</span>
      <button onClick={() => send('up')} className="p-1 rounded hover:bg-brand/10 hover:text-brand"><ThumbsUp size={13} /></button>
      <button onClick={() => send('down')} className="p-1 rounded hover:bg-rose-500/10 hover:text-rose-300"><ThumbsDown size={13} /></button>
      {done && <span className="text-brand">{done}</span>}
    </div>
  )
}

/** 👍/👎 로컬 학습 피드백 (POST /api/ai/feedback → 로컬 DuckDB + 중앙 rag). 결과가 있을 때만 노출. */
function LocalFeedbackBar({ feature, question, answer }: { feature: string; question?: string; answer?: any }) {
  const [done, setDone] = useState('')
  if (answer == null) return null
  const ans = typeof answer === 'string' ? answer : JSON.stringify(answer)
  const send = async (verdict: 'up' | 'down') => {
    try { await postAiFeedback({ feature, question, answer: ans, verdict }); setDone(verdict === 'up' ? '👍 반영됨' : '👎 반영됨') }
    catch { setDone('전송 실패') }
  }
  return (
    <div className="mt-2 flex items-center gap-2 text-xs text-slate-400">
      <span>이 결과가 도움이 됐나요?</span>
      <button onClick={() => send('up')} className="p-1 rounded hover:bg-brand/10 hover:text-brand"><ThumbsUp size={13} /></button>
      <button onClick={() => send('down')} className="p-1 rounded hover:bg-rose-500/10 hover:text-rose-300"><ThumbsDown size={13} /></button>
      {done && <span className="text-brand">{done}</span>}
    </div>
  )
}

/** 인용 라벨 — 문서명·위치·근거지지도. citation/source 객체 형태 방어적 처리. */
function citeLabel(c: any): string {
  if (c == null) return '문서'
  if (typeof c === 'string') return c
  const src = c.source || c.document || c.doc || c.title || c.chunk_id || c.id || '문서'
  const loc = c.page != null ? ` p.${c.page}` : (c.location ? ` ${c.location}` : '')
  const sup = c.support != null ? ` · ${Math.round(Number(c.support) * 100)}%` : ''
  return `${src}${loc}${sup}`
}

/**
 * WISE 근거 UX — 인용 카드(sources/citations) + 환각차단(abstained) 배지.
 * node = 응답의 defect / interpretation 서브객체. 근거·보류 정보가 있을 때만 노출.
 */
function WiseEvidence({ node }: { node: any }) {
  if (node == null) return null
  const citations: any[] = Array.isArray(node.citations) ? node.citations : []
  const sources: any[] = Array.isArray(node.sources) ? node.sources : []
  const items = citations.length ? citations : sources
  const abstained = node.abstained === true
  if (!abstained && items.length === 0) return null
  return (
    <div className="mt-3">
      {abstained && (
        <div className="mb-2 flex items-center gap-1.5 text-[11px] px-2.5 py-1.5 rounded-lg bg-amber-500/10 border border-amber-500/30 text-amber-300">
          <AlertTriangle size={13} /> 근거가 부족해 답변을 보류했습니다 (오류 아님 · 안내)
        </div>
      )}
      {items.length > 0 ? (
        <>
          <div className="text-[11px] text-slate-400 mb-1.5 flex items-center gap-1"><Quote size={12} /> 근거 인용 ({items.length})</div>
          <div className="flex flex-wrap gap-1.5">
            {items.map((c, i) => (
              <span key={i} className="text-[10px] px-2 py-1 rounded-md bg-card border border-edge text-slate-300">{citeLabel(c)}</span>
            ))}
          </div>
        </>
      ) : (
        <div className="text-[11px] text-slate-500">근거 문서 없음</div>
      )}
    </div>
  )
}

function Output({ data }: { data: any }) {
  if (data == null) return null
  if (typeof data === 'string') return <pre className="mt-3 text-xs text-slate-300 bg-ink border border-edge rounded p-3 whitespace-pre-wrap max-h-56 overflow-auto">{data}</pre>
  return <pre className="mt-3 text-xs text-slate-300 bg-ink border border-edge rounded p-3 whitespace-pre-wrap max-h-56 overflow-auto">{JSON.stringify(data, null, 2)}</pre>
}

export default function AiTools() {
  const [ollama, setOllama] = useState<boolean | null>(null)
  useEffect(() => { getAiStatus().then(d => setOllama(!!(d?.ollamaAvailable ?? d?.available))).catch(() => setOllama(false)) }, [])

  return (
    <div>
      <div className="flex items-center justify-between mb-6">
        <div>
          <h1 className="text-xl font-bold flex items-center gap-2"><Sparkles className="text-accent" size={20} /> WISE AI</h1>
          <p className="text-sm text-slate-400 mt-0.5">Enterprise AI for Trusted Knowledge · 근거·인용·환각차단(중앙 guardia-rag) + 불량분석·생산예측·예지보전·SPC이상 (Ollama 온프레미스 + Java 폴백)</p>
        </div>
        <span className={`flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-lg border ${ollama ? 'text-accent border-accent/30 bg-accent/10' : 'text-slate-400 border-edge bg-card'}`}>
          <span className={`w-1.5 h-1.5 rounded-full ${ollama ? 'bg-accent' : 'bg-slate-500'}`} />
          Ollama {ollama === null ? '확인 중' : ollama ? '온라인' : '오프라인 (Java 폴백)'}
        </span>
      </div>

      {/* ── 최신 기법 (중앙 guardia-rag 경유) — 대표 2개 기능 ───────────── */}
      <div className="flex items-center justify-between mb-3">
        <h2 className="text-sm font-semibold flex items-center gap-2 text-brand"><Cpu size={15} /> WISE AI · 근거 기반 분석 (RAG · 에이전틱 · 구조화)</h2>
        <Link to="/ai-techniques" className="text-xs text-slate-400 hover:text-brand underline">기법 토글 설정 →</Link>
      </div>
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-5 mb-8">
        <RagDefectTool /><RagPredictTool />
      </div>

      {/* ── 기존 AI 도구 (불변, Ollama + Java 폴백) ───────────────────── */}
      <h2 className="text-sm font-semibold text-slate-300 mb-3">기본 AI 도구</h2>
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-5">
        <DefectTool /><ForecastTool /><MaintenanceTool /><SpcTool />
        <QueryTool /><SafetyStockTool /><ScheduleTool />
      </div>
    </div>
  )
}

/** 대표 1: 불량 원인분석 + SPC 이상감지 (SPC 수치=결정론, 원인서술=/rag/agent+structured). */
function RagDefectTool() {
  const [code, setCode] = useState(''); const [ctx, setCtx] = useState('')
  const [values, setValues] = useState(''); const [ucl, setUcl] = useState(''); const [lcl, setLcl] = useState(''); const [cl, setCl] = useState('')
  const [out, setOut] = useState<any>(null); const [busy, setBusy] = useState(false)
  const run = async () => {
    setBusy(true)
    try {
      const vals = values.split(',').map(s => s.trim()).filter(Boolean).map(Number)
      const req: any = { defectCode: code, context: ctx ? [{ note: ctx }] : [] }
      if (vals.length) { req.values = vals; req.ucl = Number(ucl) || 0; req.lcl = Number(lcl) || 0; req.cl = Number(cl) || 0 }
      setOut(await ragDefectAnalysis(req))
    } finally { setBusy(false) }
  }
  return (
    <Card title="불량 원인분석 + SPC 이상감지 (RAG)" icon={<AlertTriangle size={15} />}>
      <Field label="불량 코드"><input className="inp" value={code} onChange={e => setCode(e.target.value)} placeholder="예: D-DIM-01" /></Field>
      <Field label="컨텍스트(공정/설비/자재)"><textarea className="inp" value={ctx} onChange={e => setCtx(e.target.value)} /></Field>
      <Field label="SPC 표본값(쉼표구분, 선택)"><input className="inp" value={values} onChange={e => setValues(e.target.value)} placeholder="예: 10.1, 10.3, 9.8, 10.5" /></Field>
      <div className="grid grid-cols-3 gap-2">
        <Field label="UCL"><input className="inp" value={ucl} onChange={e => setUcl(e.target.value)} /></Field>
        <Field label="LCL"><input className="inp" value={lcl} onChange={e => setLcl(e.target.value)} /></Field>
        <Field label="CL"><input className="inp" value={cl} onChange={e => setCl(e.target.value)} /></Field>
      </div>
      <Btn onClick={run} disabled={busy} size="sm"><Cpu size={13} /> {busy ? '분석 중…' : 'RCA + SPC 분석'}</Btn>
      <AppliedBadge data={out} />
      <Output data={out} />
      <WiseEvidence node={out?.defect} />
      <FeedbackBar answerId={out?.defect?.answerId} query={code} />
    </Card>
  )
}

/** 대표 2: 설비 예지보전 / 수요·생산 예측 (수치=결정론 베이스라인, 해석=/rag/agent). */
function RagPredictTool() {
  const [kind, setKind] = useState<'pdm' | 'forecast'>('forecast')
  const [eq, setEq] = useState(''); const [avail, setAvail] = useState(''); const [dt, setDt] = useState(''); const [mtbf, setMtbf] = useState('')
  const [series, setSeries] = useState(''); const [horizon, setHorizon] = useState(7)
  const [out, setOut] = useState<any>(null); const [busy, setBusy] = useState(false)
  const run = async () => {
    setBusy(true)
    try {
      const req: any = { kind }
      if (kind === 'pdm') { req.equipmentCode = eq; req.availability = Number(avail) || 0; req.downtimeCount = Number(dt) || 0; req.mtbfHours = Number(mtbf) || 0 }
      else { req.series = series.split(',').map(s => s.trim()).filter(Boolean).map(Number); req.horizon = horizon }
      setOut(await ragPredictAnalysis(req))
    } finally { setBusy(false) }
  }
  return (
    <Card title="예지보전 / 수요·생산 예측 (RAG)" icon={<TrendingUp size={15} />}>
      <div className="flex gap-2 mb-2">
        {(['forecast', 'pdm'] as const).map(k => (
          <button key={k} onClick={() => setKind(k)} className={`px-3 py-1.5 text-xs rounded-lg border ${kind === k ? 'bg-brand text-ink border-brand' : 'bg-card border-edge text-slate-300'}`}>
            {k === 'forecast' ? '수요/생산 예측' : '설비 예지보전'}
          </button>
        ))}
      </div>
      {kind === 'pdm' ? (
        <>
          <Field label="설비 코드"><input className="inp" value={eq} onChange={e => setEq(e.target.value)} placeholder="예: EQ-CNC-01" /></Field>
          <div className="grid grid-cols-3 gap-2">
            <Field label="가동률(0~1)"><input className="inp" value={avail} onChange={e => setAvail(e.target.value)} /></Field>
            <Field label="비가동 횟수"><input className="inp" value={dt} onChange={e => setDt(e.target.value)} /></Field>
            <Field label="MTBF(시간)"><input className="inp" value={mtbf} onChange={e => setMtbf(e.target.value)} /></Field>
          </div>
        </>
      ) : (
        <>
          <Field label="시계열(쉼표구분)"><input className="inp" value={series} onChange={e => setSeries(e.target.value)} placeholder="예: 100, 120, 95, 130" /></Field>
          <Field label="예측 기간(일)"><input type="number" className="inp" value={horizon} onChange={e => setHorizon(Number(e.target.value))} /></Field>
        </>
      )}
      <Btn onClick={run} disabled={busy} size="sm"><Cpu size={13} /> {busy ? '분석 중…' : '예측 + 해석'}</Btn>
      <AppliedBadge data={out} />
      <Output data={out} />
      <WiseEvidence node={out?.interpretation} />
      <FeedbackBar answerId={out?.interpretation?.answerId} query={kind} />
    </Card>
  )
}

function DefectTool() {
  const [code, setCode] = useState(''); const [ctx, setCtx] = useState(''); const [out, setOut] = useState<any>(null); const [busy, setBusy] = useState(false)
  const run = async () => { setBusy(true); try { setOut(await aiDefectRootCause({ defectCode: code, context: ctx })) } finally { setBusy(false) } }
  return (
    <Card title="불량 원인 분석" icon={<AlertTriangle size={15} />}>
      <Field label="불량 코드"><input className="inp" value={code} onChange={e => setCode(e.target.value)} placeholder="예: D-CRACK-01" /></Field>
      <Field label="컨텍스트(공정/설비/자재)"><textarea className="inp" value={ctx} onChange={e => setCtx(e.target.value)} /></Field>
      <Btn onClick={run} disabled={busy} size="sm"><Sparkles size={13} /> {busy ? '분석 중…' : '원인 분석'}</Btn>
      <Output data={out} />
      <LocalFeedbackBar feature="defect-root-cause" question={code} answer={out} />
    </Card>
  )
}

function ForecastTool() {
  const [item, setItem] = useState(''); const [days, setDays] = useState(30); const [out, setOut] = useState<any>(null); const [busy, setBusy] = useState(false)
  const run = async () => { setBusy(true); try { setOut(await aiForecast({ itemCode: item, days })) } finally { setBusy(false) } }
  return (
    <Card title="수요·생산량 예측" icon={<TrendingUp size={15} />}>
      <div className="grid grid-cols-2 gap-3">
        <Field label="품목코드"><input className="inp" value={item} onChange={e => setItem(e.target.value)} /></Field>
        <Field label="예측 기간(일)"><input type="number" className="inp" value={days} onChange={e => setDays(Number(e.target.value))} /></Field>
      </div>
      <Btn onClick={run} disabled={busy} size="sm"><Sparkles size={13} /> {busy ? '예측 중…' : '예측'}</Btn>
      <Output data={out} />
    </Card>
  )
}

function MaintenanceTool() {
  const [eq, setEq] = useState(''); const [out, setOut] = useState<any>(null); const [busy, setBusy] = useState(false)
  const run = async () => { setBusy(true); try { setOut(await aiPredictiveMaintenance({ equipmentCode: eq })) } finally { setBusy(false) } }
  return (
    <Card title="설비 예지보전" icon={<Wrench size={15} />}>
      <Field label="설비 코드"><input className="inp" value={eq} onChange={e => setEq(e.target.value)} placeholder="예: EQ-CNC-01" /></Field>
      <Btn onClick={run} disabled={busy} size="sm"><Sparkles size={13} /> {busy ? '분석 중…' : '정비 권고'}</Btn>
      <Output data={out} />
    </Card>
  )
}

function SpcTool() {
  const [code, setCode] = useState(''); const [out, setOut] = useState<any>(null); const [busy, setBusy] = useState(false)
  const run = async () => { setBusy(true); try { setOut(await aiSpcAnomaly({ chartCode: code })) } finally { setBusy(false) } }
  return (
    <Card title="SPC 이상 감지" icon={<LineChart size={15} />}>
      <Field label="관리도 코드"><input className="inp" value={code} onChange={e => setCode(e.target.value)} /></Field>
      <Btn onClick={run} disabled={busy} size="sm"><Sparkles size={13} /> {busy ? '감지 중…' : '이상 감지'}</Btn>
      <Output data={out} />
    </Card>
  )
}

function QueryTool() {
  const [q, setQ] = useState(''); const [out, setOut] = useState<any>(null); const [busy, setBusy] = useState(false)
  const run = async () => { setBusy(true); try { setOut(await aiParseQuery({ query: q })) } finally { setBusy(false) } }
  return (
    <Card title="작업지시·재고 자연어 조회" icon={<Search size={15} />}>
      <Field label="자연어 질의"><input className="inp" value={q} onChange={e => setQ(e.target.value)} placeholder="예: 지난주 지연된 작업지시" onKeyDown={e => e.key === 'Enter' && run()} /></Field>
      <Btn onClick={run} disabled={busy} size="sm"><Sparkles size={13} /> {busy ? '해석 중…' : '질의 해석'}</Btn>
      <Output data={out} />
      <LocalFeedbackBar feature="parse-query" question={q} answer={out} />
    </Card>
  )
}

function SafetyStockTool() {
  const [item, setItem] = useState(''); const [out, setOut] = useState<any>(null); const [busy, setBusy] = useState(false)
  const run = async () => { setBusy(true); try { setOut(await aiSafetyStock({ itemCode: item })) } finally { setBusy(false) } }
  return (
    <Card title="재고 최적화·안전재고 추천" icon={<Boxes size={15} />}>
      <Field label="품목코드"><input className="inp" value={item} onChange={e => setItem(e.target.value)} /></Field>
      <Btn onClick={run} disabled={busy} size="sm"><Sparkles size={13} /> {busy ? '분석 중…' : '추천'}</Btn>
      <Output data={out} />
    </Card>
  )
}

function ScheduleTool() {
  const [out, setOut] = useState<any>(null); const [busy, setBusy] = useState(false)
  const run = async () => { setBusy(true); try { setOut(await aiScheduleOptimize({})) } finally { setBusy(false) } }
  return (
    <Card title="생산 일정 최적화" icon={<CalendarClock size={15} />}>
      <p className="text-xs text-slate-400 mb-2">현재 작업지시·설비 부하 기반으로 일정 최적화를 제안합니다.</p>
      <Btn onClick={run} disabled={busy} size="sm"><Sparkles size={13} /> {busy ? '최적화 중…' : '일정 최적화 제안'}</Btn>
      <Output data={out} />
    </Card>
  )
}
