import { useCallback, useEffect, useState } from 'react'
import { ApiError, getOrgs, type Org } from './api/client'
import LoginPage from './components/LoginPage'
import OrgDetail from './components/OrgDetail'
import OrgList from './components/OrgList'
import SeedUpload from './components/SeedUpload'

// 'checking'이 필요하다. true로 시작하면 첫 렌더에서 getOrgs()가 아직 안 끝났는데도
// 로그인한 것처럼 빈 껍데기를 먼저 보여주고, 401이 온 뒤에야 로그인 화면으로 튄다.
//
// 'error'는 401이 아닌 실패(서버 500, 네트워크 단절 등)를 위한 상태다. 이런 오류까지
// '로그아웃'으로 취급해 로그인 화면으로 보내면, 로그인해도 같은 오류가 반복되고
// 원인을 알 수 없게 된다 - 세션은 멀쩡한데 서버/네트워크만 문제인 경우이므로
// 오류 메시지와 재시도 버튼을 보여주는 편이 맞다.
type AuthState = 'checking' | 'authenticated' | 'anonymous' | 'error'

export default function App() {
  const [orgs, setOrgs] = useState<Org[]>([])
  const [selectedId, setSelectedId] = useState<number | null>(null)
  const [auth, setAuth] = useState<AuthState>('checking')
  const [authErrorMessage, setAuthErrorMessage] = useState<string | null>(null)

  const reload = useCallback(async () => {
    try {
      setOrgs(await getOrgs())
      setAuth('authenticated')
    } catch (e) {
      if (e instanceof ApiError && e.status === 401) {
        setAuth('anonymous')
      } else {
        setAuthErrorMessage((e as Error).message)
        setAuth('error')
      }
    }
  }, [])

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

  if (auth === 'checking') {
    return <div className="p-8 text-sm text-gray-500">불러오는 중…</div>
  }

  if (auth === 'anonymous') {
    return <LoginPage onSuccess={() => void reload()} />
  }

  if (auth === 'error') {
    return (
      <div className="flex min-h-screen flex-col items-center justify-center gap-3 p-8 text-sm">
        <p className="text-red-600">{authErrorMessage}</p>
        <button
          type="button"
          onClick={() => void reload()}
          className="rounded-md border border-gray-300 px-3 py-1.5 text-sm"
        >
          다시 시도
        </button>
      </div>
    )
  }

  const selected = orgs.find((org) => org.id === selectedId) ?? null

  return (
    <div className="flex h-screen">
      <div className="flex w-80 flex-col border-r border-gray-200">
        <OrgList orgs={orgs} selectedId={selectedId} onSelect={setSelectedId} />
        <SeedUpload onUploaded={() => void reload()} />
      </div>

      <main className="flex-1 overflow-y-auto">
        {selected ? (
          <OrgDetail org={selected} onChanged={() => void reload()} />
        ) : (
          <p className="p-8 text-sm text-gray-500">왼쪽에서 기관을 선택하세요.</p>
        )}
      </main>
    </div>
  )
}
