// 관리자(ADMIN JWT) 인증 공용 모듈 — 관리자 패널·포탈이 공유.
// 토큰은 Gucci(/gucci/auth/login)에서 발급받아 localStorage에 보관하고, /admin/* 호출에 Bearer로 첨부한다.
import { useEffect, useState } from 'react'

const TOKEN_KEY = 'rtgs_admin_token'
const USER_KEY = 'rtgs_admin_user'

type Listener = () => void
const listeners = new Set<Listener>()
const emit = () => listeners.forEach((l) => l())

export const getToken = () => localStorage.getItem(TOKEN_KEY)
export const getUser = () => localStorage.getItem(USER_KEY) || ''
export function setSession(token: string, user: string) {
  localStorage.setItem(TOKEN_KEY, token); localStorage.setItem(USER_KEY, user); emit()
}
export function clearToken() {
  localStorage.removeItem(TOKEN_KEY); localStorage.removeItem(USER_KEY); emit()
}

export function authHeader(json = false): Record<string, string> {
  const h: Record<string, string> = {}
  if (json) h['Content-Type'] = 'application/json'
  const t = getToken(); if (t) h['Authorization'] = `Bearer ${t}`
  return h
}

/** 401이면 토큰을 비우고 예외. */
export async function authedFetch(url: string, init: RequestInit = {}): Promise<Response> {
  const r = await fetch(url, init)
  if (r.status === 401) { clearToken(); throw new Error('세션 만료 또는 권한 없음 — 다시 로그인하세요') }
  return r
}

export async function jget(url: string): Promise<any> {
  const r = await authedFetch(url, { headers: authHeader() }); return r.json()
}
export async function jsend(url: string, body?: any, method = 'POST'): Promise<any> {
  const r = await authedFetch(url, { method, headers: authHeader(!!body), body: body ? JSON.stringify(body) : undefined })
  return r.json()
}

/** 로그인 → ADMIN 검증 → 세션 저장. 성공 시 {ok:true, mustChange}. */
export async function login(username: string, secret: string): Promise<{ ok: boolean; mustChange?: boolean; error?: string }> {
  try {
    const resp = await fetch('/gucci/auth/login', {
      method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, secret }),
    })
    if (!resp.ok) return { ok: false, error: '로그인 실패 — 아이디/비밀번호를 확인하세요' }
    const r = await resp.json()
    if (r.role !== 'ADMIN') return { ok: false, error: '관리자(ADMIN) 권한이 필요합니다' }
    setSession(r.token, username)
    return { ok: true, mustChange: !!r.mustChangePassword }
  } catch (e: any) { return { ok: false, error: '로그인 실패: ' + e.message } }
}

export async function changePassword(username: string, oldSecret: string, newSecret: string): Promise<{ ok: boolean; error?: string }> {
  try {
    const resp = await fetch('/gucci/auth/change-password', {
      method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, oldSecret, newSecret }),
    })
    if (!resp.ok) return { ok: false, error: '비밀번호 변경 실패' }
    return { ok: true }
  } catch (e: any) { return { ok: false, error: '변경 실패: ' + e.message } }
}

/** 토큰 상태를 구독하는 훅(여러 컴포넌트 동기화). */
export function useAuth() {
  const [token, setToken] = useState<string | null>(() => getToken())
  useEffect(() => {
    const l = () => setToken(getToken())
    listeners.add(l)
    return () => { listeners.delete(l) }
  }, [])
  return { token, user: getUser(), logout: clearToken }
}
