import { useEffect, useState } from 'react'
import {
  codeGroupList, codeGroupDetail, createCodeGroup, updateCodeGroup, deleteCodeGroup,
} from '../../../api/uiws'
import {
  PageHeader, Panel, SearchBar, Input, Button, DataGrid, Modal, FormField, Spinner, YnBadge, type Column,
} from '../../../components/uiws/ui'

interface CodeGrp extends Record<string, unknown> { grpCd: string; grpNm: string; useYn: string }
interface CodeValue extends Record<string, unknown> { grpCd?: string; codeVal: string; codeNm: string; sortOrd: number; useYn: string }
interface CodeGrpDetail extends CodeGrp { values: CodeValue[] }

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

export default function CodeManagement() {
  const [groups, setGroups] = useState<CodeGrp[]>([])
  const [activeGrp, setActiveGrp] = useState<string>('')
  const [detail, setDetail] = useState<CodeGrpDetail | null>(null)
  const [keyword, setKeyword] = useState('')
  const [loadingGrp, setLoadingGrp] = useState(false)
  const [loadingDetail, setLoadingDetail] = useState(false)
  const [err, setErr] = useState('')
  const [form, setForm] = useState<{ open: boolean; edit: CodeGrpDetail | null }>({ open: false, edit: null })

  const loadGroups = async (kw = '') => {
    setLoadingGrp(true); setErr('')
    try {
      const res = await codeGroupList(kw || undefined)
      // CMS 백엔드 그룹목록은 PageResponse → data.content
      const list: CodeGrp[] = res.data.data?.content ?? []
      setGroups(list)
      if (!activeGrp && list.length > 0) setActiveGrp(list[0].grpCd)
    } catch (e) { setErr(friendlyError(e)) }
    finally { setLoadingGrp(false) }
  }
  useEffect(() => { loadGroups('') }, [])

  const loadDetail = async (grp = activeGrp) => {
    if (!grp) { setDetail(null); return }
    setLoadingDetail(true)
    try {
      const res = await codeGroupDetail(grp)
      const d = res.data.data
      setDetail(d ? { ...d, values: d.values ?? [] } : null)
    } catch (e) { setErr(friendlyError(e)) }
    finally { setLoadingDetail(false) }
  }
  useEffect(() => { loadDetail() }, [activeGrp])

  const removeGroup = async (grpCd: string) => {
    if (!window.confirm(`코드그룹 '${grpCd}' 와 하위 코드를 삭제하시겠습니까?`)) return
    try {
      await deleteCodeGroup(grpCd)
      if (activeGrp === grpCd) { setActiveGrp(''); setDetail(null) }
      await loadGroups(keyword)
    } catch (e) { setErr(friendlyError(e)) }
  }

  const codeColumns: Column<CodeValue>[] = [
    { key: 'codeVal', header: '코드값', width: 170 },
    { key: 'codeNm', header: '코드명' },
    { key: 'sortOrd', header: '정렬', width: 70, align: 'center' },
    { key: 'useYn', header: '사용', width: 80, align: 'center', render: r => <YnBadge yn={r.useYn} yes="사용" no="미사용" /> },
  ]

  return (
    <div className="uiws-scope">
      <PageHeader title="공통코드 관리" subtitle="시스템관리(권한) · 코드그룹/코드값 일괄 CRUD"
        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={() => loadGroups(keyword)}>검색</Button>
      </SearchBar>

      <div style={{ display: 'grid', gridTemplateColumns: '300px 1fr', gap: 16, alignItems: 'start' }}>
        <Panel style={{ padding: 0 }}>
          <div style={{ padding: '12px 16px', fontSize: 12, fontWeight: 600, color: 'var(--uiws-text-muted)', borderBottom: '1px solid var(--uiws-border)' }}>
            코드그룹
          </div>
          {loadingGrp ? <Spinner /> : (
            <div>
              {groups.length === 0 && <div style={{ padding: 20, fontSize: 13, color: 'var(--uiws-text-faint)' }}>코드그룹이 없습니다.</div>}
              {groups.map(g => (
                <div key={g.grpCd} onClick={() => setActiveGrp(g.grpCd)}
                  style={{
                    padding: '11px 16px', cursor: 'pointer', fontSize: 13, display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                    borderLeft: `3px solid ${activeGrp === g.grpCd ? 'var(--uiws-primary)' : 'transparent'}`,
                    background: activeGrp === g.grpCd ? 'var(--uiws-primary-soft)' : 'transparent',
                  }}>
                  <div>
                    <div style={{ fontWeight: 600, color: activeGrp === g.grpCd ? 'var(--uiws-primary)' : 'var(--uiws-text)' }}>{g.grpNm}</div>
                    <div style={{ fontSize: 11, color: 'var(--uiws-text-muted)' }}>{g.grpCd}</div>
                  </div>
                  <div style={{ display: 'flex', gap: 6 }} onClick={e => e.stopPropagation()}>
                    <Button variant="ghost" onClick={() => removeGroup(g.grpCd)}>삭제</Button>
                  </div>
                </div>
              ))}
            </div>
          )}
        </Panel>

        <div>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
            <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--uiws-text)' }}>
              코드값 {activeGrp && <span style={{ color: 'var(--uiws-text-muted)', fontWeight: 400 }}>({activeGrp})</span>}
            </div>
            <Button onClick={() => detail && setForm({ open: true, edit: detail })} disabled={!detail}>그룹·코드값 편집</Button>
          </div>
          {loadingDetail ? <Spinner /> : (
            <DataGrid columns={codeColumns} rows={detail?.values ?? []} rowKey={r => `${activeGrp}:${r.codeVal}`}
              empty={activeGrp ? '코드값이 없습니다.' : '코드그룹을 선택하세요.'} />
          )}
        </div>
      </div>

      {form.open && (
        <CodeGroupForm grp={form.edit} onClose={() => setForm({ open: false, edit: null })}
          onSaved={async (grpCd) => {
            setForm({ open: false, edit: null })
            await loadGroups(keyword)
            if (grpCd) { setActiveGrp(grpCd); await loadDetail(grpCd) }
            else await loadDetail()
          }} />
      )}
    </div>
  )
}

function SelectYn({ value, onChange }: { value: string; onChange: (v: string) => void }) {
  return (
    <select value={value} onChange={e => onChange(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="Y">사용</option>
      <option value="N">미사용</option>
    </select>
  )
}

function CodeGroupForm({ grp, onClose, onSaved }: { grp: CodeGrpDetail | null; onClose: () => void; onSaved: (grpCd: string) => void }) {
  const editing = !!grp
  const [grpCd, setGrpCd] = useState(grp?.grpCd ?? '')
  const [grpNm, setGrpNm] = useState(grp?.grpNm ?? '')
  const [useYn, setUseYn] = useState(grp?.useYn ?? 'Y')
  const [values, setValues] = useState<CodeValue[]>(grp?.values ? grp.values.map(v => ({ ...v })) : [])
  const [err, setErr] = useState('')

  const addValue = () => setValues(prev => [...prev, { codeVal: '', codeNm: '', sortOrd: prev.length + 1, useYn: 'Y' }])
  const updateValue = (idx: number, field: keyof CodeValue, val: string | number) =>
    setValues(prev => prev.map((v, i) => (i === idx ? { ...v, [field]: val } : v)))
  const removeValue = (idx: number) => setValues(prev => prev.filter((_, i) => i !== idx))

  const save = async () => {
    setErr('')
    if (!editing && !grpCd.trim()) { setErr('그룹코드는 필수입니다.'); return }
    if (!grpNm.trim()) { setErr('그룹명은 필수입니다.'); return }
    for (const v of values) {
      if (!v.codeVal.trim() || !v.codeNm.trim()) { setErr('코드값과 코드명은 필수입니다.'); return }
    }
    try {
      const body = {
        grpCd, grpNm, useYn,
        values: values.map(v => ({ grpCd, codeVal: v.codeVal, codeNm: v.codeNm, sortOrd: Number(v.sortOrd) || 0, useYn: v.useYn })),
      }
      editing ? await updateCodeGroup(grpCd, body) : await createCodeGroup(body)
      onSaved(grpCd)
    } catch (e) { setErr(friendlyError(e)) }
  }

  const cellInput: React.CSSProperties = {
    width: '100%', padding: '6px 8px', borderRadius: 6, fontSize: 12,
    background: 'var(--uiws-input-bg)', border: '1px solid var(--uiws-border)', color: 'var(--uiws-text)',
  }

  return (
    <Modal title={editing ? '코드그룹·코드값 편집' : '코드그룹 등록'} onClose={onClose}
      footer={<><Button variant="ghost" onClick={onClose}>취소</Button><Button onClick={save}>저장</Button></>}>
      <FormField label="그룹코드"><Input value={grpCd} onChange={setGrpCd} style={{ width: '100%', opacity: editing ? 0.6 : 1 }} /></FormField>
      <FormField label="그룹명"><Input value={grpNm} onChange={setGrpNm} style={{ width: '100%' }} /></FormField>
      <FormField label="사용 여부"><SelectYn value={useYn} onChange={setUseYn} /></FormField>

      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 8, marginBottom: 8 }}>
        <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--uiws-text-muted)' }}>코드값 ({values.length})</div>
        <Button variant="ghost" onClick={addValue}>+ 코드값 추가</Button>
      </div>
      <div style={{ border: '1px solid var(--uiws-border)', borderRadius: 8, overflow: 'hidden' }}>
        <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12, color: 'var(--uiws-text)' }}>
          <thead>
            <tr style={{ background: 'var(--uiws-surface-2)' }}>
              <th style={{ padding: '7px 8px', textAlign: 'left', color: 'var(--uiws-text-muted)', fontWeight: 600 }}>코드값</th>
              <th style={{ padding: '7px 8px', textAlign: 'left', color: 'var(--uiws-text-muted)', fontWeight: 600 }}>코드명</th>
              <th style={{ padding: '7px 8px', width: 64, color: 'var(--uiws-text-muted)', fontWeight: 600 }}>정렬</th>
              <th style={{ padding: '7px 8px', width: 76, color: 'var(--uiws-text-muted)', fontWeight: 600 }}>사용</th>
              <th style={{ padding: '7px 8px', width: 44 }} />
            </tr>
          </thead>
          <tbody>
            {values.length === 0 ? (
              <tr><td colSpan={5} style={{ padding: 16, textAlign: 'center', color: 'var(--uiws-text-faint)' }}>코드값이 없습니다.</td></tr>
            ) : values.map((v, idx) => (
              <tr key={idx} style={{ borderTop: '1px solid var(--uiws-border)' }}>
                <td style={{ padding: '5px 8px' }}>
                  <input value={v.codeVal} onChange={e => updateValue(idx, 'codeVal', e.target.value)} style={cellInput} />
                </td>
                <td style={{ padding: '5px 8px' }}>
                  <input value={v.codeNm} onChange={e => updateValue(idx, 'codeNm', e.target.value)} style={cellInput} />
                </td>
                <td style={{ padding: '5px 8px' }}>
                  <input type="number" value={String(v.sortOrd)} onChange={e => updateValue(idx, 'sortOrd', Number(e.target.value) || 0)} style={cellInput} />
                </td>
                <td style={{ padding: '5px 8px' }}>
                  <select value={v.useYn} onChange={e => updateValue(idx, 'useYn', e.target.value)} style={cellInput}>
                    <option value="Y">사용</option>
                    <option value="N">미사용</option>
                  </select>
                </td>
                <td style={{ padding: '5px 8px', textAlign: 'center' }}>
                  <button onClick={() => removeValue(idx)}
                    style={{ background: 'none', border: 'none', color: 'var(--uiws-danger)', cursor: 'pointer', fontSize: 16 }}>×</button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      {err && <div style={{ color: 'var(--uiws-danger)', fontSize: 13, marginTop: 10 }}>{err}</div>}
    </Modal>
  )
}
