const TOKEN_KEY = 'ligbox_console_token'
const USER_KEY = 'ligbox_console_user'
const SSO_COOKIE = 'ligbox_sso_token'

function readSsoCookieToken() {
  const re = new RegExp(`(?:^|; )${SSO_COOKIE.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\$&')}=([^;]*)`)
  const m = document.cookie.match(re)
  return m ? decodeURIComponent(m[1]) : null
}

const DNS_VIEWER_ROLES = new Set([
  'super_admin',
  'ops_lead',
  'technician',
  'noc',
  'seo',
  'devops',
  'developer',
])

export function getToken() {
  return localStorage.getItem(TOKEN_KEY)
}

export function getUser() {
  try {
    return JSON.parse(localStorage.getItem(USER_KEY) || 'null')
  } catch {
    return null
  }
}

export function setSession(token, user) {
  localStorage.setItem(TOKEN_KEY, token)
  localStorage.setItem(USER_KEY, JSON.stringify(user))
}

export function clearSession() {
  localStorage.removeItem(TOKEN_KEY)
  localStorage.removeItem(USER_KEY)
}

export function isLoggedIn() {
  return Boolean(getToken())
}

export function canReadDnsViewer(role) {
  return DNS_VIEWER_ROLES.has(role)
}

function userFromLoginResponse(data) {
  return (
    data.user || {
      username: data.username,
      role: data.role,
      display_name: data.display_name,
    }
  )
}

export async function refreshSession() {
  const token = getToken()
  if (!token) return false
  const { apiGet } = await import('./api')
  const me = await apiGet('/api/v1/auth/me', { token })
  setSession(token, {
    username: me.username,
    role: me.role,
    display_name: me.display_name,
  })
  return true
}

export async function exchangeDeskHandoff(handoffToken) {
  const { apiPost } = await import('./api')
  const data = await apiPost('/api/v1/auth/console-handoff/exchange', {
    handoff_token: handoffToken,
  })
  setSession(data.access_token, userFromLoginResponse(data))
  return data
}

async function bootstrapFromSsoCookie() {
  const cookieToken = readSsoCookieToken()
  if (!cookieToken) return false
  setSession(cookieToken, getUser() || {})
  try {
    await refreshSession()
    return true
  } catch {
    clearSession()
    return false
  }
}

/** Handoff URL, cookie Desk (.ligbox.com.br) ou JWT Console — uma vez no shell /admin. */
export async function bootstrapAuthFromUrl() {
  const params = new URLSearchParams(window.location.search)
  const handoff = params.get('desk_handoff')
  if (handoff) {
    try {
      await exchangeDeskHandoff(handoff)
      params.delete('desk_handoff')
      const qs = params.toString()
      const path = `${window.location.pathname}${qs ? `?${qs}` : ''}`
      window.history.replaceState({}, '', path)
      return true
    } catch (e) {
      console.warn('desk handoff failed', e)
    }
  }
  if (!isLoggedIn()) {
    const fromCookie = await bootstrapFromSsoCookie()
    if (fromCookie) return true
    return false
  }
  try {
    await refreshSession()
    return true
  } catch {
    clearSession()
    const fromCookie = await bootstrapFromSsoCookie()
    return fromCookie
  }
}

export async function loginDesk(username, password) {
  const { apiPost } = await import('./api')
  const data = await apiPost('/api/v1/auth/login', { username, password })
  if (data.mfa_required) {
    throw new Error('2FA necessário — entre pelo Desk e use «Abrir no Console» no DNS')
  }
  setSession(data.access_token, userFromLoginResponse(data))
  return data
}
