const AUTH_STORAGE_KEY = 'ten-minute-planner-auth'
import { buildApiUrl, toUserFacingApiError } from './apiBase'

function buildHeaders(token, hasBody, extraHeaders = {}) {
  return {
    ...(hasBody ? { 'Content-Type': 'application/json' } : {}),
    ...(token ? { Authorization: `Bearer ${token}` } : {}),
    ...extraHeaders,
  }
}

async function request(path, { method = 'GET', token, body } = {}) {
  const hasBody = body !== undefined
  const response = await fetch(buildApiUrl(path), {
    method,
    headers: buildHeaders(token, hasBody),
    body: hasBody ? JSON.stringify(body) : undefined,
  })

  const data = await response.json().catch(() => ({}))

  if (!response.ok) {
    throw new Error(toUserFacingApiError(data, '요청 처리 중 문제가 발생했습니다.'))
  }

  return data
}

export function readAuthState() {
  if (typeof window === 'undefined') {
    return { token: '', user: null, persist: false }
  }

  try {
    const localState = JSON.parse(window.localStorage.getItem(AUTH_STORAGE_KEY) ?? 'null')

    if (localState?.token) {
      return { ...localState, persist: true }
    }

    const sessionState = JSON.parse(window.sessionStorage.getItem(AUTH_STORAGE_KEY) ?? 'null')

    if (sessionState?.token) {
      return { ...sessionState, persist: false }
    }

    return { token: '', user: null, persist: false }
  } catch (error) {
    console.warn('저장된 인증 상태를 불러오지 못했습니다.', error)
    return { token: '', user: null, persist: false }
  }
}

export function persistAuthState({ token, user, persist = false }) {
  if (typeof window === 'undefined') {
    return
  }

  const targetStorage = persist ? window.localStorage : window.sessionStorage
  const unusedStorage = persist ? window.sessionStorage : window.localStorage

  unusedStorage.removeItem(AUTH_STORAGE_KEY)
  targetStorage.setItem(AUTH_STORAGE_KEY, JSON.stringify({ token, user }))
}

export function clearAuthState() {
  if (typeof window === 'undefined') {
    return
  }

  window.localStorage.removeItem(AUTH_STORAGE_KEY)
  window.sessionStorage.removeItem(AUTH_STORAGE_KEY)
}

export async function signup({ email, password, nickname }) {
  return request('/api/auth/signup', {
    method: 'POST',
    body: { email, password, nickname },
  })
}

export async function login({ email, password }) {
  return request('/api/auth/login', {
    method: 'POST',
    body: { email, password },
  })
}

export async function fetchCurrentUser(token) {
  return request('/api/auth/me', {
    token,
  })
}

export async function logout(token) {
  return request('/api/auth/logout', {
    method: 'POST',
    token,
  })
}

export async function updateProfile(token, { email, nickname }) {
  return request('/api/auth/profile', {
    method: 'PUT',
    token,
    body: { email, nickname },
  })
}

export async function updatePassword(token, { currentPassword, newPassword }) {
  return request('/api/auth/password', {
    method: 'PUT',
    token,
    body: { currentPassword, newPassword },
  })
}

export async function deleteAccount(token, { currentPassword }) {
  return request('/api/auth/account', {
    method: 'DELETE',
    token,
    body: { currentPassword },
  })
}

export async function requestPasswordReset({ email }) {
  return request('/api/auth/password-reset/request', {
    method: 'POST',
    body: { email },
  })
}

export async function confirmPasswordReset({ token, newPassword }) {
  return request('/api/auth/password-reset/confirm', {
    method: 'POST',
    body: { token, newPassword },
  })
}

export async function confirmVerification({ token }) {
  return request('/api/auth/verification/confirm', {
    method: 'POST',
    body: { token },
  })
}

export async function requestVerification({ email }, token) {
  return request('/api/auth/verification/request', {
    method: 'POST',
    token,
    body: email ? { email } : {},
  })
}
