import { useEffect, useState } from 'react'
import { ListTree, Plus, Trash2, ChevronRight, Search } from 'lucide-react'
import { PageHeader, Btn, Field, Modal, Empty } from '../components/ui'
import { canManage } from '../components/rbac'
import { getBomTree, getAllBom, createBom, updateBom, deleteBom, getItems } from '../api/client'

const emptyForm = { parentItemCode: '', childItemCode: '', qtyPer: 1, seq: 1, lossRate: 0, bomVersion: 'v1' }

// 평면 목록 → 트리 (parentItemCode 기준)
function buildTree(rows: any[], rootCode: string) {
  const byParent: Record<string, any[]> = {}
  rows.forEach(r => { (byParent[r.parentItemCode] = byParent[r.parentItemCode] || []).push(r) })
  const walk = (code: string, depth: number, seen: Set<string>): any[] => {
    if (seen.has(code) || depth > 8) return []
    seen.add(code)
    return (byParent[code] || []).flatMap(r => [
      { ...r, depth },
      ...walk(r.childItemCode, depth + 1, new Set(seen)),
    ])
  }
  return walk(rootCode, 0, new Set())
}

export default function Bom() {
  const [parentCode, setParentCode] = useState('')
  const [version, setVersion] = useState('')
  const [tree, setTree] = useState<any[]>([])
  const [all, setAll] = useState<any[]>([])
  const [editor, setEditor] = useState<any>(null)
  const [items, setItems] = useState<any[]>([])
  const manageable = canManage()

  const loadAll = () => getAllBom().then(d => setAll(Array.isArray(d) ? d : [])).catch(() => setAll([]))
  const loadTree = () => {
    if (!parentCode) { setTree([]); return }
    getBomTree({ parentItemCode: parentCode, bomVersion: version }).then(d => {
      const rows = Array.isArray(d) ? d : (d?.rows || d?.nodes || [])
      // 서버가 평면 반환 시 트리화, 이미 트리면 그대로
      setTree(rows.some((r: any) => r.depth != null) ? rows : buildTree(rows, parentCode))
    }).catch(() => setTree([]))
  }
  useEffect(() => { loadAll(); getItems().then(d => setItems(d || [])).catch(() => {}) }, [])
  useEffect(() => { loadTree() }, [parentCode, version])

  const openNew = () => setEditor({ ...emptyForm, parentItemCode: parentCode, _new: true })
  const save = async () => {
    const { _new, id, ...payload } = editor
    if (_new) await createBom(payload); else await updateBom(id, payload)
    setEditor(null); loadAll(); loadTree()
  }
  const remove = async (id: number) => { if (!window.confirm('삭제하시겠습니까?')) return; await deleteBom(id); loadAll(); loadTree() }

  const products = items.filter((it: any) => ['PRODUCT', 'SEMI'].includes(it.itemType))

  return (
    <div>
      <PageHeader title="BOM" subtitle="자재 구성(Bill of Materials) · 소요량 · 버전 · 트리 전개"
        actions={manageable && <Btn onClick={openNew}><Plus size={16} /> BOM 행</Btn>} />

      <div className="flex flex-wrap items-center gap-2 mb-5">
        <select className="inp w-56" value={parentCode} onChange={e => setParentCode(e.target.value)}>
          <option value="">상위 품목 선택</option>
          {products.map((it: any) => <option key={it.id} value={it.itemCode}>{it.itemName} ({it.itemCode})</option>)}
        </select>
        <input className="inp w-28" placeholder="버전" value={version} onChange={e => setVersion(e.target.value)} />
        <Btn variant="ghost" onClick={loadTree}><Search size={15} /> 전개</Btn>
      </div>

      {/* 트리 전개 */}
      <div className="bg-card border border-edge rounded-xl overflow-hidden mb-6">
        <table className="w-full text-sm">
          <thead className="text-slate-500 text-xs bg-panel">
            <tr><th className="text-left py-3 px-4">구성 (트리)</th><th className="text-left">하위 품목</th><th className="text-right">소요량</th><th className="text-right">손실률</th><th className="text-left">버전</th><th className="text-right px-4">작업</th></tr>
          </thead>
          <tbody>
            {tree.map((r: any, i: number) => (
              <tr key={r.id ?? i} className="border-t border-edge/50">
                <td className="py-2.5 px-4" style={{ paddingLeft: 16 + (r.depth || 0) * 20 }}>
                  <span className="flex items-center gap-1 text-slate-300"><ChevronRight size={12} className="text-brand" />{r.childItemName || r.childItemCode}</span>
                </td>
                <td className="text-slate-400 font-mono text-xs">{r.childItemCode}</td>
                <td className="text-right text-slate-300">{r.qtyPer}</td>
                <td className="text-right text-slate-400 text-xs">{r.lossRate != null ? `${r.lossRate}%` : '-'}</td>
                <td className="text-slate-400 text-xs">{r.bomVersion || '-'}</td>
                <td className="px-4">
                  {manageable && <div className="flex items-center justify-end gap-2">
                    <button onClick={() => setEditor({ ...r, _new: false })} className="text-xs text-slate-400 hover:text-brand">편집</button>
                    <button onClick={() => remove(r.id)} className="text-rose-400 hover:text-rose-300"><Trash2 size={14} /></button>
                  </div>}
                </td>
              </tr>
            ))}
            {tree.length === 0 && <Empty colSpan={6} msg={parentCode ? '구성이 없습니다.' : '상위 품목을 선택하면 BOM 트리가 전개됩니다.'} />}
          </tbody>
        </table>
      </div>

      {/* 전체 BOM */}
      <h3 className="text-sm font-semibold mb-2 flex items-center gap-1.5"><ListTree size={15} className="text-brand" /> 전체 BOM</h3>
      <div className="bg-card border border-edge rounded-xl overflow-hidden">
        <table className="w-full text-sm">
          <thead className="text-slate-500 text-xs bg-panel">
            <tr><th className="text-left py-3 px-4">상위</th><th className="text-left">하위</th><th className="text-right">소요량</th><th className="text-left">버전</th></tr>
          </thead>
          <tbody>
            {all.slice(0, 100).map((r: any) => (
              <tr key={r.id} className="border-t border-edge/50">
                <td className="py-2.5 px-4 text-slate-300">{r.parentItemCode}</td>
                <td className="text-slate-400">{r.childItemCode}</td>
                <td className="text-right text-slate-300">{r.qtyPer}</td>
                <td className="text-slate-400 text-xs">{r.bomVersion || '-'}</td>
              </tr>
            ))}
            {all.length === 0 && <Empty colSpan={4} msg="BOM이 없습니다." />}
          </tbody>
        </table>
      </div>

      {editor && (
        <Modal title={editor._new ? 'BOM 행 추가' : 'BOM 행 편집'} onClose={() => setEditor(null)}>
          <div className="space-y-3">
            <Field label="상위 품목">
              <select className="inp" value={editor.parentItemCode} onChange={e => setEditor({ ...editor, parentItemCode: e.target.value })}>
                <option value="">선택</option>
                {products.map((it: any) => <option key={it.id} value={it.itemCode}>{it.itemName} ({it.itemCode})</option>)}
              </select>
            </Field>
            <Field label="하위 품목">
              <select className="inp" value={editor.childItemCode} onChange={e => setEditor({ ...editor, childItemCode: e.target.value })}>
                <option value="">선택</option>
                {items.map((it: any) => <option key={it.id} value={it.itemCode}>{it.itemName} ({it.itemCode})</option>)}
              </select>
            </Field>
            <div className="grid grid-cols-3 gap-3">
              <Field label="소요량"><input type="number" step="any" className="inp" value={editor.qtyPer} onChange={e => setEditor({ ...editor, qtyPer: Number(e.target.value) })} /></Field>
              <Field label="순서"><input type="number" className="inp" value={editor.seq} onChange={e => setEditor({ ...editor, seq: Number(e.target.value) })} /></Field>
              <Field label="손실률(%)"><input type="number" step="any" className="inp" value={editor.lossRate} onChange={e => setEditor({ ...editor, lossRate: Number(e.target.value) })} /></Field>
            </div>
            <Field label="버전"><input className="inp" value={editor.bomVersion} onChange={e => setEditor({ ...editor, bomVersion: e.target.value })} /></Field>
          </div>
          <div className="flex justify-end gap-2 mt-5">
            <Btn variant="ghost" onClick={() => setEditor(null)}>취소</Btn>
            <Btn onClick={save}>저장</Btn>
          </div>
        </Modal>
      )}
    </div>
  )
}
