import { useEffect, useState } from 'react'
import { menuList, menuCreate, menuUpdate, menuDelete, programList } from '../../../api/uiws'
import { PageHeader, Panel, Button, Modal, FormField, Input, Spinner, Pagination, YnBadge, DataGrid, type Column } from '../../../components/uiws/ui'
import AdminGate from './AdminGate'

/**
 * 2.9 메뉴 관리 — /api/system/menus. 목록(PageResponse, 기본 size 100)/등록/수정/다중삭제(본문 ids).
 * 프로그램(2.8) 연결 select. RBAC 변경 ADMIN/MANAGER(403 + AdminGate). 색상 토큰만.
 */
type Menu = { menuId: string; menuNm: string; parentMenuId: string; programId: string; menuUrl: string; sortOrd: number | null; useYn: string }
type Program = { programId: string; programNm: string }
const empty: Menu = { menuId: '', menuNm: '', parentMenuId: '', programId: '', menuUrl: '', sortOrd: null, useYn: 'Y' }
const PSIZE = 100

function friendlyError(e: any): string {
  if (e?.response?.status === 403) return '권한이 없습니다 (관리자 전용).'
  if (e?.response?.status === 409) return '이미 존재하는 메뉴 ID입니다.'
  return e?.response?.data?.message || '요청을 처리하지 못했습니다.'
}

export default function MenuManagement() {
  const [rows, setRows] = useState<Menu[]>([])
  const [total, setTotal] = useState(0)
  const [page, setPage] = useState(0)
  const [programs, setPrograms] = useState<Program[]>([])
  const [loading, setLoading] = useState(false)
  const [sel, setSel] = useState<Set<string>>(new Set())
  const [open, setOpen] = useState(false)
  const [editing, setEditing] = useState(false)
  const [form, setForm] = useState<Menu>(empty)
  const [err, setErr] = useState('')

  async function load(p = page) {
    setLoading(true)
    try {
      const res = await menuList({ page: p, size: PSIZE })
      setRows(res.data?.data?.content || [])
      setTotal(res.data?.data?.total || 0)
      setSel(new Set())
    } catch { setRows([]); setTotal(0) } finally { setLoading(false) }
  }
  async function loadPrograms() {
    try { const res = await programList({ page: 0, size: 200 }); setPrograms(res.data?.data?.content || []) } catch { setPrograms([]) }
  }
  useEffect(() => { load(0); loadPrograms() }, [])

  function openCreate() { setForm(empty); setEditing(false); setErr(''); setOpen(true) }
  function openEdit(m: Menu) { setForm({ ...m }); setEditing(true); setErr(''); setOpen(true) }

  async function save() {
    setErr('')
    if (!form.menuId.trim() || !form.menuNm.trim()) { setErr('메뉴 ID와 이름은 필수입니다.'); return }
    try {
      if (editing) await menuUpdate(form.menuId, form)
      else await menuCreate(form)
      setOpen(false); load()
    } catch (e) { setErr(friendlyError(e)) }
  }
  async function removeSelected() {
    if (sel.size === 0) return
    if (!confirm(`선택한 ${sel.size}개 메뉴를 삭제할까요?`)) return
    try { await menuDelete([...sel]); load() } catch (e) { alert(friendlyError(e)) }
  }

  const toggle = (id: string) => setSel(p => { const n = new Set(p); n.has(id) ? n.delete(id) : n.add(id); return n })
  const totalPages = Math.max(1, Math.ceil(total / PSIZE))

  const columns: Column<Menu & Record<string, unknown>>[] = [
    { key: 'sel', header: '', width: 36, render: r => (
      <input type="checkbox" checked={sel.has(r.menuId)} onChange={() => toggle(r.menuId)} onClick={e => e.stopPropagation()} />
    ) },
    { key: 'menuId', header: '메뉴 ID', render: r => <span className="font-mono">{r.menuId}</span> },
    { key: 'menuNm', header: '메뉴명' },
    { key: 'parentMenuId', header: '상위' },
    { key: 'programId', header: '프로그램' },
    { key: 'menuUrl', header: 'URL' },
    { key: 'sortOrd', header: '순서', width: 60 },
    { key: 'useYn', header: '사용', width: 80, render: r => <YnBadge yn={r.useYn} yes="사용" no="미사용" /> },
  ]

  return (
    <AdminGate>
      <div className="uiws-scope">
        <PageHeader title="메뉴 관리" subtitle="시스템 메뉴 트리/프로그램 연결"
          actions={<>
            <Button variant="danger" onClick={removeSelected} disabled={sel.size === 0}>삭제 ({sel.size})</Button>
            <Button onClick={openCreate}>메뉴 추가</Button>
          </>} />

        {loading ? <Spinner /> : (
          <>
            <DataGrid columns={columns} rows={rows as (Menu & Record<string, unknown>)[]} rowKey={r => r.menuId}
              onRowClick={r => openEdit(r)} empty="등록된 메뉴가 없습니다." />
            <Pagination page={page} totalPages={totalPages} onChange={p => { setPage(p); load(p) }} />
          </>
        )}

        {open && (
          <Modal title={editing ? '메뉴 수정' : '메뉴 추가'} onClose={() => setOpen(false)}>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
              <FormField label="메뉴 ID"><Input value={form.menuId} onChange={v => setForm({ ...form, menuId: v })} style={{ width: '100%' }} /></FormField>
              <FormField label="메뉴명"><Input value={form.menuNm} onChange={v => setForm({ ...form, menuNm: v })} style={{ width: '100%' }} /></FormField>
              <FormField label="상위 메뉴 ID"><Input value={form.parentMenuId} onChange={v => setForm({ ...form, parentMenuId: v })} style={{ width: '100%' }} /></FormField>
              <FormField label="프로그램">
                <select value={form.programId} onChange={e => setForm({ ...form, programId: e.target.value })}
                  style={{ width: '100%', padding: '9px 12px', borderRadius: 8, fontSize: 13, background: 'var(--uiws-input-bg)', border: '1px solid var(--uiws-border)', color: 'var(--uiws-text)' }}>
                  <option value="">(선택 안 함)</option>
                  {programs.map(p => <option key={p.programId} value={p.programId}>{p.programNm} ({p.programId})</option>)}
                </select>
              </FormField>
              <FormField label="메뉴 URL"><Input value={form.menuUrl} onChange={v => setForm({ ...form, menuUrl: v })} style={{ width: '100%' }} /></FormField>
              <FormField label="정렬 순서"><Input type="number" value={String(form.sortOrd ?? '')} onChange={v => setForm({ ...form, sortOrd: v === '' ? null : Number(v) })} style={{ width: '100%' }} /></FormField>
            </div>
            <FormField label="사용 여부"><Input value={form.useYn} onChange={v => setForm({ ...form, useYn: v })} placeholder="Y / N" /></FormField>
            {err && <p className="text-xs" style={{ color: 'var(--uiws-danger)' }}>{err}</p>}
            <div className="flex justify-end gap-2 pt-2">
              <Button variant="ghost" onClick={() => setOpen(false)}>취소</Button>
              <Button onClick={save}>저장</Button>
            </div>
          </Modal>
        )}
      </div>
    </AdminGate>
  )
}
