import { useEffect, useMemo, useState } from 'react'
import { menuList, createMenu, updateMenu, deleteMenu } from '../../../api/uiws'
import {
  PageHeader, SearchBar, Input, Button, DataGrid, Modal, FormField, Spinner, YnBadge, type Column,
} from '../../../components/uiws/ui'

interface Menu extends Record<string, unknown> {
  menuId: string; menuNm: string; parentMenuId: string | null; programId: string | null
  menuUrl: string | null; sortOrd: number; useYn: string
}

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 [keyword, setKeyword] = useState('')
  const [loading, setLoading] = useState(false)
  const [err, setErr] = useState('')
  const [form, setForm] = useState<{ open: boolean; edit: Menu | null }>({ open: false, edit: null })

  const load = async () => {
    setLoading(true); setErr('')
    try { const res = await menuList(); setRows(res.data.data?.content ?? []) }
    catch (e) { setErr(friendlyError(e)) }
    finally { setLoading(false) }
  }
  useEffect(() => { load() }, [])

  // 검색은 클라이언트 필터(메뉴 목록은 풀로드). 부모가 매치되면 자식도 함께 보이도록 정렬 전 적용.
  const filtered = useMemo(() => {
    const kw = keyword.trim().toLowerCase()
    if (!kw) return rows
    return rows.filter(r => r.menuNm.toLowerCase().includes(kw) || r.menuId.toLowerCase().includes(kw))
  }, [rows, keyword])

  // 2-depth: 부모 → 자식 순으로 정렬해 들여쓰기 표시.
  const ordered = useMemo(() => {
    const rows = filtered
    const roots = rows.filter(r => !r.parentMenuId).sort((a, b) => (a.sortOrd ?? 0) - (b.sortOrd ?? 0))
    const out: { menu: Menu; depth: number }[] = []
    for (const root of roots) {
      out.push({ menu: root, depth: 0 })
      rows.filter(r => r.parentMenuId === root.menuId)
        .sort((a, b) => (a.sortOrd ?? 0) - (b.sortOrd ?? 0))
        .forEach(c => out.push({ menu: c, depth: 1 }))
    }
    // 부모가 목록에 없는 고아 항목도 표시
    const seen = new Set(out.map(o => o.menu.menuId))
    rows.filter(r => !seen.has(r.menuId)).forEach(m => out.push({ menu: m, depth: 0 }))
    return out.map(o => ({ ...o.menu, _depth: o.depth })) as (Menu & { _depth: number })[]
  }, [filtered])

  const remove = async (m: Menu) => {
    if (!window.confirm(`메뉴 '${m.menuNm}' 를 삭제하시겠습니까?`)) return
    try { await deleteMenu(m.menuId); await load() }
    catch (e) { setErr(friendlyError(e)) }
  }

  const columns: Column<Menu & { _depth: number }>[] = [
    {
      key: 'menuNm', header: '메뉴명',
      render: r => (
        <span style={{ paddingLeft: r._depth * 22 }}>
          {r._depth > 0 && <span style={{ color: 'var(--uiws-text-faint)' }}>└ </span>}
          {r.menuNm} <span style={{ color: 'var(--uiws-text-muted)', fontSize: 12 }}>({r.menuId})</span>
        </span>
      ),
    },
    { key: 'menuUrl', header: 'URL', width: 220, render: r => r.menuUrl ?? '-' },
    { key: 'programId', header: '프로그램', width: 140, render: r => r.programId ?? '-' },
    { key: 'sortOrd', header: '정렬', width: 70, align: 'center' },
    { key: 'useYn', header: '사용', width: 80, align: 'center', render: r => <YnBadge yn={r.useYn} yes="사용" no="미사용" /> },
    { key: 'act', header: '', width: 60, align: 'center', render: r => <Button variant="ghost" onClick={() => remove(r)}>삭제</Button> },
  ]

  return (
    <div className="uiws-scope">
      <PageHeader title="메뉴 관리" subtitle="시스템관리(권한) · 메뉴 트리(2-depth) 등록/수정/삭제"
        actions={<Button onClick={() => setForm({ open: true, edit: null })}>+ 메뉴 등록</Button>} />

      {err && <div style={{ color: 'var(--uiws-danger)', fontSize: 13, marginBottom: 12 }}>{err}</div>}

      <SearchBar>
        <Input value={keyword} onChange={setKeyword} placeholder="메뉴명 검색" style={{ minWidth: 220 }} />
        <Button variant="ghost" onClick={() => { /* 클라이언트 필터(keyword 상태) — 재조회 불필요 */ }}>검색</Button>
      </SearchBar>

      {loading ? <Spinner /> : (
        <DataGrid columns={columns} rows={ordered} rowKey={r => r.menuId}
          onRowClick={r => setForm({ open: true, edit: r })} empty="등록된 메뉴가 없습니다." />
      )}

      {form.open && (
        <MenuForm menu={form.edit} parents={rows.filter(r => !r.parentMenuId)}
          onClose={() => setForm({ open: false, edit: null })}
          onSaved={() => { setForm({ open: false, edit: null }); load() }} />
      )}
    </div>
  )
}

function MenuForm({ menu, parents, onClose, onSaved }: {
  menu: Menu | null; parents: Menu[]; onClose: () => void; onSaved: () => void
}) {
  const editing = !!menu
  const [menuId, setMenuId] = useState(menu?.menuId ?? '')
  const [menuNm, setMenuNm] = useState(menu?.menuNm ?? '')
  const [parentMenuId, setParentMenuId] = useState(menu?.parentMenuId ?? '')
  const [programId, setProgramId] = useState(menu?.programId ?? '')
  const [menuUrl, setMenuUrl] = useState(menu?.menuUrl ?? '')
  const [sortOrd, setSortOrd] = useState(String(menu?.sortOrd ?? 0))
  const [useYn, setUseYn] = useState(menu?.useYn ?? 'Y')
  const [err, setErr] = useState('')

  const save = async () => {
    setErr('')
    if (!editing && !menuId.trim()) { setErr('메뉴ID는 필수입니다.'); return }
    if (!menuNm.trim()) { setErr('메뉴명은 필수입니다.'); return }
    try {
      const body = {
        menuId, menuNm, parentMenuId: parentMenuId || null, programId: programId || null,
        menuUrl: menuUrl || null, sortOrd: Number(sortOrd) || 0, useYn,
      }
      editing ? await updateMenu(menuId, body) : await createMenu(body)
      onSaved()
    } catch (e) { setErr(friendlyError(e)) }
  }

  const selStyle = {
    width: '100%', padding: '9px 12px', borderRadius: 8, fontSize: 13,
    background: 'var(--uiws-input-bg)', border: '1px solid var(--uiws-border)', color: 'var(--uiws-text)',
  } as const

  return (
    <Modal title={editing ? '메뉴 수정' : '메뉴 등록'} onClose={onClose}
      footer={<><Button variant="ghost" onClick={onClose}>취소</Button><Button onClick={save}>저장</Button></>}>
      <FormField label="메뉴ID"><Input value={menuId} onChange={setMenuId} style={{ width: '100%', opacity: editing ? 0.6 : 1 }} /></FormField>
      <FormField label="메뉴명"><Input value={menuNm} onChange={setMenuNm} style={{ width: '100%' }} /></FormField>
      <FormField label="상위 메뉴">
        <select value={parentMenuId} onChange={e => setParentMenuId(e.target.value)} style={selStyle}>
          <option value="">(최상위)</option>
          {parents.filter(p => p.menuId !== menuId).map(p => <option key={p.menuId} value={p.menuId}>{p.menuNm} ({p.menuId})</option>)}
        </select>
      </FormField>
      <FormField label="프로그램ID"><Input value={programId} onChange={setProgramId} style={{ width: '100%' }} /></FormField>
      <FormField label="메뉴 URL"><Input value={menuUrl} onChange={setMenuUrl} style={{ width: '100%' }} /></FormField>
      <FormField label="정렬순서"><Input type="number" value={sortOrd} onChange={setSortOrd} style={{ width: '100%' }} /></FormField>
      <FormField label="사용 여부">
        <select value={useYn} onChange={e => setUseYn(e.target.value)} style={selStyle}>
          <option value="Y">사용</option>
          <option value="N">미사용</option>
        </select>
      </FormField>
      {err && <div style={{ color: 'var(--uiws-danger)', fontSize: 13 }}>{err}</div>}
    </Modal>
  )
}
