import { useEffect, useRef, useState } from 'react'
import {
  createContact,
  deleteContact,
  getContacts,
  importMembers,
  updateContactInfo,
  type Contact,
  type ContactCategory,
  type ContactInput,
  type MemberImportReport,
} from '../api/client'
import HelpButton from '../help/HelpButton'

const CATEGORY_LABELS: Record<ContactCategory, string> = {
  APPLICANT: '신청기관',
  MJ: '문정원',
  LAWYER: '변호사',
  OPERATOR: '수행기관',
  ITN: '아이티앤 담당자',
}

const CATEGORY_BADGE_STYLES: Record<ContactCategory, string> = {
  APPLICANT: 'bg-blue-50 text-blue-700',
  MJ: 'bg-emerald-50 text-emerald-700',
  LAWYER: 'bg-violet-50 text-violet-700',
  OPERATOR: 'bg-sky-50 text-sky-700',
  ITN: 'bg-orange-50 text-orange-700',
}

const FILTERS: { key: ContactCategory | 'ALL'; label: string }[] = [
  { key: 'ALL', label: '전체' },
  { key: 'APPLICANT', label: '신청기관' },
  { key: 'MJ', label: '문정원' },
  { key: 'LAWYER', label: '변호사' },
  { key: 'OPERATOR', label: '수행기관' },
  { key: 'ITN', label: '아이티앤 담당자' },
]

function emptyForm(contact: Contact | null): ContactInput {
  return {
    category: contact?.category ?? 'APPLICANT',
    name: contact?.name ?? '',
    affiliation: contact?.affiliation ?? '',
    deptName: contact?.deptName ?? '',
    title: contact?.title ?? '',
    phone: contact?.phone ?? '',
    email: contact?.email ?? '',
  }
}

function ContactFormModal({
  editing,
  onClose,
  onSaved,
}: {
  editing: Contact | null
  onClose: () => void
  onSaved: () => void
}) {
  const [form, setForm] = useState<ContactInput>(emptyForm(editing))
  const [busy, setBusy] = useState(false)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    function onKeyDown(e: KeyboardEvent) {
      if (e.key === 'Escape') {
        onClose()
      }
    }
    window.addEventListener('keydown', onKeyDown)
    return () => window.removeEventListener('keydown', onKeyDown)
  }, [onClose])

  const canSave = form.category.trim() !== '' && form.name.trim() !== '' && !busy

  function setField(key: keyof ContactInput, value: string) {
    setForm((prev) => ({ ...prev, [key]: value }))
  }

  async function handleSave() {
    if (!canSave) {
      return
    }
    setBusy(true)
    setError(null)
    try {
      if (editing) {
        await updateContactInfo(editing.id, form)
      } else {
        await createContact(form)
      }
      onSaved()
    } catch (e) {
      setError(e instanceof Error ? e.message : '저장에 실패했습니다.')
    } finally {
      setBusy(false)
    }
  }

  return (
    <div className="fixed inset-0 flex items-center justify-center bg-black/30">
      <div className="w-[26rem] rounded-lg bg-white p-5">
        <div className="flex items-center justify-between">
          <h2 className="text-base font-semibold">{editing ? '담당자 수정' : '담당자 추가'}</h2>
          <button
            type="button"
            onClick={onClose}
            aria-label="닫기"
            disabled={busy}
            className="rounded-md p-1 text-gray-400 hover:bg-gray-100 disabled:opacity-50"
          >
            ✕
          </button>
        </div>

        <div className="mt-4 grid grid-cols-2 gap-3 text-sm">
          <div className="flex flex-col gap-1">
            <label htmlFor="contact-category" className="text-xs text-gray-500">
              구분
            </label>
            <select
              id="contact-category"
              value={form.category}
              onChange={(e) => setField('category', e.target.value)}
              className="rounded-md border border-gray-300 px-2 py-1.5"
            >
              <option value="APPLICANT">신청기관</option>
              <option value="MJ">문정원</option>
              <option value="LAWYER">변호사</option>
              <option value="OPERATOR">수행기관</option>
              <option value="ITN">아이티앤 담당자</option>
            </select>
          </div>
          <div className="flex flex-col gap-1">
            <label htmlFor="contact-name" className="text-xs text-gray-500">
              성명
            </label>
            <input
              id="contact-name"
              value={form.name}
              onChange={(e) => setField('name', e.target.value)}
              className="rounded-md border border-gray-300 px-2 py-1.5"
            />
          </div>
          <div className="flex flex-col gap-1">
            <label htmlFor="contact-affiliation" className="text-xs text-gray-500">
              소속
            </label>
            <input
              id="contact-affiliation"
              value={form.affiliation}
              onChange={(e) => setField('affiliation', e.target.value)}
              className="rounded-md border border-gray-300 px-2 py-1.5"
            />
          </div>
          <div className="flex flex-col gap-1">
            <label htmlFor="contact-dept" className="text-xs text-gray-500">
              부서
            </label>
            <input
              id="contact-dept"
              value={form.deptName}
              onChange={(e) => setField('deptName', e.target.value)}
              className="rounded-md border border-gray-300 px-2 py-1.5"
            />
          </div>
          <div className="flex flex-col gap-1">
            <label htmlFor="contact-title" className="text-xs text-gray-500">
              직급/직함
            </label>
            <input
              id="contact-title"
              value={form.title}
              onChange={(e) => setField('title', e.target.value)}
              className="rounded-md border border-gray-300 px-2 py-1.5"
            />
          </div>
          <div className="flex flex-col gap-1">
            <label htmlFor="contact-phone" className="text-xs text-gray-500">
              연락처
            </label>
            <input
              id="contact-phone"
              value={form.phone}
              onChange={(e) => setField('phone', e.target.value)}
              className="rounded-md border border-gray-300 px-2 py-1.5"
            />
          </div>
          <div className="col-span-2 flex flex-col gap-1">
            <label htmlFor="contact-email" className="text-xs text-gray-500">
              이메일
            </label>
            <input
              id="contact-email"
              value={form.email}
              onChange={(e) => setField('email', e.target.value)}
              className="rounded-md border border-gray-300 px-2 py-1.5"
            />
          </div>
        </div>

        {error && <p className="mt-3 text-xs text-red-600">{error}</p>}

        <div className="mt-5 flex justify-end gap-2">
          <button
            type="button"
            disabled={busy}
            onClick={onClose}
            className="rounded-md border border-gray-300 px-3 py-1.5 text-sm disabled:opacity-50"
          >
            취소
          </button>
          <button
            type="button"
            disabled={!canSave}
            onClick={() => void handleSave()}
            className="rounded-md bg-blue-600 px-3 py-1.5 text-sm text-white disabled:bg-gray-300"
          >
            저장
          </button>
        </div>
      </div>
    </div>
  )
}

/** 담당자관리 화면. 담당자 정보가 입력되는 유일한 곳이다 - 채널관리는 여기 등록된
 * 담당자를 ContactPickerModal로 골라 배정만 한다. */
export default function ContactsPage() {
  const [contacts, setContacts] = useState<Contact[]>([])
  const [loading, setLoading] = useState(true)
  const [filter, setFilter] = useState<ContactCategory | 'ALL'>('ALL')
  const [modalOpen, setModalOpen] = useState(false)
  const [editing, setEditing] = useState<Contact | null>(null)
  const [error, setError] = useState<string | null>(null)

  const importInputRef = useRef<HTMLInputElement>(null)
  const [importBusy, setImportBusy] = useState(false)
  const [importReport, setImportReport] = useState<MemberImportReport | null>(null)
  const [importError, setImportError] = useState<string | null>(null)

  async function load() {
    setLoading(true)
    try {
      setContacts(await getContacts())
    } catch (e) {
      setError(e instanceof Error ? e.message : '담당자 목록을 불러오지 못했습니다.')
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    void load()
  }, [])

  const visible = filter === 'ALL' ? contacts : contacts.filter((c) => c.category === filter)

  function openAdd() {
    setEditing(null)
    setModalOpen(true)
  }

  function openEdit(contact: Contact) {
    setEditing(contact)
    setModalOpen(true)
  }

  function closeModal() {
    setModalOpen(false)
    setEditing(null)
  }

  async function handleSaved() {
    closeModal()
    await load()
  }

  async function handleDelete(contact: Contact) {
    if (!window.confirm('삭제하면 기관에 지정된 배정도 함께 해제됩니다. 삭제할까요?')) {
      return
    }
    try {
      await deleteContact(contact.id)
      await load()
    } catch (e) {
      setError(e instanceof Error ? e.message : '삭제에 실패했습니다.')
    }
  }

  async function handleImportFile(file: File) {
    setImportBusy(true)
    setImportError(null)
    try {
      const report = await importMembers(file)
      setImportReport(report)
      await load()
    } catch (e) {
      setImportError(e instanceof Error ? e.message : '회원명단 업로드에 실패했습니다.')
    } finally {
      setImportBusy(false)
    }
  }

  return (
    <div className="p-8">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <div className="flex flex-wrap gap-2">
          {FILTERS.map((f) => (
            <button
              key={f.key}
              type="button"
              onClick={() => setFilter(f.key)}
              aria-current={filter === f.key ? 'true' : undefined}
              className={`rounded-full px-3 py-1.5 text-sm ${
                filter === f.key
                  ? 'bg-gray-900 text-white'
                  : 'border border-gray-300 text-gray-600 hover:bg-gray-50'
              }`}
            >
              {f.label}
            </button>
          ))}
        </div>

        <div className="flex items-center gap-2">
          <input
            ref={importInputRef}
            type="file"
            accept=".xlsx,.xlsm"
            className="hidden"
            onChange={(e) => {
              const file = e.target.files?.[0]
              if (file) void handleImportFile(file)
              e.target.value = ''
            }}
          />
          <button
            type="button"
            disabled={importBusy}
            onClick={() => importInputRef.current?.click()}
            className="rounded-md border border-gray-300 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-50 disabled:opacity-50"
          >
            {importBusy ? '업로드 중…' : '회원명단 업로드'}
          </button>
          <button
            type="button"
            onClick={openAdd}
            className="rounded-md bg-blue-600 px-3 py-1.5 text-sm text-white hover:bg-blue-700"
          >
            담당자 추가
          </button>
          <span className="flex items-center">
            <HelpButton topic="contacts.manage" />
          </span>
        </div>
      </div>

      {importReport && (
        <p className="mt-4 text-sm text-gray-600">
          {`등록 ${importReport.created} · 갱신 ${importReport.updated} · 기관지정 ${importReport.assigned} · 건너뜀 ${importReport.skipped}`}
        </p>
      )}
      {importError && <p className="mt-4 text-sm text-red-600">{importError}</p>}
      {error && <p className="mt-4 text-sm text-red-600">{error}</p>}

      <div className="mt-5 overflow-x-auto rounded-lg border border-gray-200 bg-white">
        <table className="w-full min-w-[860px] text-sm">
          <thead>
            <tr className="border-b border-gray-200 bg-gray-50 text-left text-xs text-gray-500">
              <th className="whitespace-nowrap px-3 py-2 font-medium">구분</th>
              <th className="whitespace-nowrap px-3 py-2 font-medium">성명</th>
              <th className="whitespace-nowrap px-3 py-2 font-medium">소속</th>
              <th className="whitespace-nowrap px-3 py-2 font-medium">부서</th>
              <th className="whitespace-nowrap px-3 py-2 font-medium">직급/직함</th>
              <th className="whitespace-nowrap px-3 py-2 font-medium">연락처</th>
              <th className="whitespace-nowrap px-3 py-2 font-medium">이메일</th>
              <th className="whitespace-nowrap px-3 py-2 font-medium">관리</th>
            </tr>
          </thead>
          <tbody>
            {loading ? (
              <tr>
                <td colSpan={8} className="py-8 text-center text-sm text-gray-400">
                  불러오는 중…
                </td>
              </tr>
            ) : visible.length === 0 ? (
              <tr>
                <td colSpan={8} className="py-8 text-center text-sm text-gray-300">
                  등록된 담당자가 없습니다.
                </td>
              </tr>
            ) : (
              visible.map((contact) => (
                <tr key={contact.id} className="border-b border-gray-100 last:border-b-0">
                  <td className="px-3 py-2">
                    <span
                      className={`rounded-full px-2 py-0.5 text-xs font-medium ${CATEGORY_BADGE_STYLES[contact.category]}`}
                    >
                      {CATEGORY_LABELS[contact.category]}
                    </span>
                  </td>
                  <td className="px-3 py-2 font-medium text-gray-900">{contact.name}</td>
                  <td className="px-3 py-2 text-gray-600">{contact.affiliation ?? '-'}</td>
                  <td className="px-3 py-2 text-gray-600">{contact.deptName ?? '-'}</td>
                  <td className="px-3 py-2 text-gray-600">{contact.title ?? '-'}</td>
                  <td className="px-3 py-2 text-gray-600">{contact.phone ?? '-'}</td>
                  <td className="px-3 py-2 text-gray-600">{contact.email ?? '-'}</td>
                  <td className="px-3 py-2">
                    <div className="flex gap-2">
                      <button
                        type="button"
                        onClick={() => openEdit(contact)}
                        className="rounded-md border border-gray-200 px-2 py-0.5 text-xs text-gray-600 hover:bg-gray-50"
                      >
                        수정
                      </button>
                      <button
                        type="button"
                        onClick={() => void handleDelete(contact)}
                        className="rounded-md border border-gray-200 px-2 py-0.5 text-xs text-gray-600 hover:bg-gray-50"
                      >
                        삭제
                      </button>
                    </div>
                  </td>
                </tr>
              ))
            )}
          </tbody>
        </table>
      </div>

      {modalOpen && (
        <ContactFormModal editing={editing} onClose={closeModal} onSaved={() => void handleSaved()} />
      )}
    </div>
  )
}
