import { useCallback, useEffect, useState } from 'react'
import {
  getResetPreview,
  resetChannels,
  RESET_CONFIRM_PHRASE,
  type ResetReport,
  type ResetTarget,
} from '../api/client'
import { stageLabel } from '../stages'
import HelpButton from '../help/HelpButton'

/**
 * 시스템관리 화면. 지금은 [채널 초기화] 하나만 있다.
 *
 * 되돌리기 번거로운 작업이라 3중으로 막는다.
 *   1) 무엇이 사라지는지 목록으로 먼저 보여준다
 *   2) 확인 문구를 그대로 입력해야 버튼이 열린다
 *   3) 서버도 같은 문구를 다시 검사한다
 *
 * 지우는 범위는 <b>웹앱이 만든(=DB가 채널 ID를 들고 있는) 채널</b>뿐이다. Mattermost 팀에는
 * 엑셀 VBA로 만든 예전 채널과 공용 채널(Town Square/FAQ/대쉬보드/양식 모음/자료실)이 함께
 * 있어서, 이름으로 훑어 지우면 그것들까지 날아간다. 사용자 계정도 건드리지 않는다.
 */

interface Props {
  /** 초기화가 끝나면 상위(App)가 기관 목록을 다시 읽도록. */
  onChanged?: () => void
}

export default function SystemPage({ onChanged }: Props) {
  const [targets, setTargets] = useState<ResetTarget[] | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [confirm, setConfirm] = useState('')
  const [busy, setBusy] = useState(false)
  const [report, setReport] = useState<ResetReport | null>(null)
  const [dialogOpen, setDialogOpen] = useState(false)

  const reload = useCallback(async () => {
    try {
      setTargets(await getResetPreview())
      setError(null)
    } catch (e) {
      setError((e as Error).message)
    }
  }, [])

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

  const channelCount = (targets ?? []).reduce((sum, t) => sum + t.channels.length, 0)
  const canRun = confirm.trim() === RESET_CONFIRM_PHRASE && channelCount > 0 && !busy

  async function run() {
    setBusy(true)
    setDialogOpen(false)
    try {
      const result = await resetChannels(confirm.trim())
      setReport(result)
      setConfirm('')
      await reload()
      onChanged?.()
      setError(null)
    } catch (e) {
      setError((e as Error).message)
    } finally {
      setBusy(false)
    }
  }

  return (
    <div className="space-y-4 p-6">
      <section className="rounded-lg border border-gray-200 bg-white p-5">
        <h1 className="text-lg font-semibold">시스템관리</h1>
        <p className="text-xs text-gray-500">운영 중 되돌리기가 필요한 작업을 모아 둔다.</p>
      </section>

      <section className="rounded-lg border border-red-200 bg-white p-5">
        <h2 className="flex items-center gap-1.5 text-sm font-semibold text-red-700">
          채널 초기화
          <HelpButton topic="system.reset" />
        </h2>
        <ul className="mt-3 space-y-1 rounded-md bg-red-50 p-3 text-xs text-red-800">
          <li>· 웹앱이 만든 Mattermost 채널을 <b>보관(아카이브)</b> 처리한다. 영구 삭제가 아니라 시스템 콘솔에서 되돌릴 수 있다.</li>
          <li>· 기관의 채널 연결과 진행단계가 비워져, 채널관리에서 처음부터 다시 만들 수 있게 된다.</li>
          <li>· 담당자 배정, 권리확인·권리처리 자료, 업무메모는 <b>그대로 남는다</b>.</li>
          <li>· 공용 채널(Town Square·FAQ·대쉬보드·양식 모음·자료실)과 엑셀로 만든 예전 채널은 대상이 아니다.</li>
          <li>· 사용자 계정도 건드리지 않는다.</li>
        </ul>

        {error && (
          <p className="mt-3 rounded-md bg-red-50 px-3 py-2 text-sm text-red-700">{error}</p>
        )}

        {report && (
          <div className="mt-3 rounded-md bg-gray-50 px-3 py-2 text-sm">
            <p>
              채널 {report.archivedChannels}개 보관, 기관 {report.clearedOrgs}곳 초기화
              {report.failures.length > 0 && `, 실패 ${report.failures.length}건`}
            </p>
            {report.failures.length > 0 && (
              <ul className="mt-1 space-y-0.5 text-xs text-red-700">
                {report.failures.map((f) => (
                  <li key={f}>· {f}</li>
                ))}
              </ul>
            )}
          </div>
        )}

        <div className="mt-4">
          <p className="text-sm font-medium">
            대상 {targets?.length ?? 0}개 기관 · 채널 {channelCount}개
          </p>

          {targets === null ? (
            <p className="mt-2 text-sm text-gray-500">불러오는 중…</p>
          ) : targets.length === 0 ? (
            <p className="mt-2 text-sm text-gray-500">초기화할 채널이 없습니다.</p>
          ) : (
            <div className="mt-2 max-h-72 overflow-y-auto rounded-md border border-gray-200">
              <table data-testid="reset-targets" className="w-full text-sm">
                <thead>
                  <tr className="border-b border-gray-200 text-xs text-gray-500">
                    <th className="px-3 py-2 text-left font-normal">연번</th>
                    <th className="px-3 py-2 text-left font-normal">기관명</th>
                    <th className="px-3 py-2 text-left font-normal">현재 단계</th>
                    <th className="px-3 py-2 text-left font-normal">보관될 채널</th>
                  </tr>
                </thead>
                <tbody>
                  {targets.map((t) => (
                    <tr key={t.orgId} className="border-b border-gray-100">
                      <td className="px-3 py-2 text-gray-500 tabular-nums">{t.orgNo}</td>
                      <td className="px-3 py-2 font-medium">{t.orgName}</td>
                      <td className="px-3 py-2 text-gray-600">
                        {t.stage === null ? '-' : `${t.stage}. ${stageLabel(t.stage)}`}
                      </td>
                      <td className="px-3 py-2 text-gray-600">
                        {t.channels.map((c) => c.kind).join(' · ')}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>

        <div className="mt-4 flex flex-wrap items-center gap-2">
          <label htmlFor="reset-confirm" className="text-sm text-gray-600">
            실행하려면 <b>{RESET_CONFIRM_PHRASE}</b> 를 입력하세요
          </label>
          <input
            id="reset-confirm"
            value={confirm}
            onChange={(e) => setConfirm(e.target.value)}
            className="w-40 rounded-md border border-gray-300 px-2 py-1.5 text-sm"
          />
          <button
            type="button"
            disabled={!canRun}
            onClick={() => setDialogOpen(true)}
            className="rounded-md bg-red-600 px-3 py-1.5 text-sm text-white disabled:bg-gray-300"
          >
            채널 초기화 실행
          </button>
        </div>
      </section>

      {dialogOpen && (
        <div className="fixed inset-0 flex items-center justify-center bg-black/30" role="alertdialog">
          <div className="w-96 rounded-lg bg-white p-5">
            <h2 className="text-base font-semibold">정말 초기화할까요?</h2>
            <p className="mt-3 rounded-md bg-gray-50 p-3 text-sm text-gray-700">
              기관 {targets?.length ?? 0}곳의 채널 {channelCount}개가 Mattermost에서 보관 처리되고,
              해당 기관의 채널 연결과 진행단계가 비워집니다.
            </p>
            <div className="mt-5 flex justify-end gap-2">
              <button
                type="button"
                disabled={busy}
                onClick={() => setDialogOpen(false)}
                className="rounded-md border border-gray-300 px-3 py-1.5 text-sm disabled:opacity-50"
              >
                취소
              </button>
              <button
                type="button"
                disabled={busy}
                onClick={() => void run()}
                className="rounded-md bg-red-600 px-3 py-1.5 text-sm text-white disabled:bg-gray-300"
              >
                초기화 실행
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}
