import { defineStore } from 'pinia'
import { ref } from 'vue'
import { getPortalUser } from 'src/api/portal'

/**
 * Customer session store.
 *
 * Two hydration paths:
 *   1. Magic-link JWT in the URL (`?token=JWT`). Decoded client-side — the
 *      hub already signed it and the user received it through their own
 *      verified channel (SMS/email), so trust is established. No network
 *      call needed.
 *   2. ERPNext session (legacy / staff impersonation). Only tried when
 *      there's no token AND no existing store state. Failure is silent —
 *      the router guard will bounce the user to /login.
 *
 * For the token path we also strip `?token=` from the URL so a page refresh
 * or bookmark doesn't replay the token forever. The store state carries us
 * for the rest of the session; if the user refreshes without a token, the
 * guard sees `customerId` still set and lets them through.
 */

function readTokenFromLocation () {
  if (typeof window === 'undefined') return ''
  const hash = window.location.hash || ''
  // Hash form: #/paiement/merci?token=xxx OR #/?token=xxx
  const qIdx = hash.indexOf('?')
  if (qIdx === -1) return ''
  const qs = new URLSearchParams(hash.slice(qIdx + 1))
  return qs.get('token') || ''
}

function decodeJwtPayload (token) {
  try {
    const parts = token.split('.')
    if (parts.length !== 3) return null
    const payload = JSON.parse(atob(parts[1].replace(/-/g, '+').replace(/_/g, '/')))
    if (payload.exp && Date.now() / 1000 > payload.exp) return null
    return payload
  } catch {
    return null
  }
}

function stripTokenFromUrl () {
  if (typeof window === 'undefined') return
  const hash = window.location.hash || ''
  const qIdx = hash.indexOf('?')
  if (qIdx === -1) return
  const before = hash.slice(0, qIdx)
  const params = new URLSearchParams(hash.slice(qIdx + 1))
  params.delete('token')
  const rest = params.toString()
  const newHash = rest ? `${before}?${rest}` : before
  // Use replaceState so the token doesn't stay in browser history
  window.history.replaceState(null, '', window.location.pathname + window.location.search + newHash)
}

export const useCustomerStore = defineStore('customer', () => {
  const email = ref('')
  const customerId = ref('')
  const customerName = ref('')
  const loading = ref(true)
  const error = ref(null)

  function hydrateFromToken () {
    const token = readTokenFromLocation()
    if (!token) return false
    const payload = decodeJwtPayload(token)
    if (!payload || payload.scope !== 'customer') return false
    customerId.value = payload.sub
    customerName.value = payload.name || payload.sub
    email.value = payload.email || ''
    stripTokenFromUrl()
    return true
  }

  async function init () {
    loading.value = true
    error.value = null
    try {
      // Path 1: magic-link token in URL
      if (hydrateFromToken()) return

      // Already authenticated in this tab? (e.g. subsequent nav)
      if (customerId.value) return

      // Path 2: fall back to ERPNext session (staff impersonation / legacy)
      const user = await getPortalUser()
      email.value = user.email
      customerId.value = user.customer_id
      customerName.value = user.customer_name
    } catch (e) {
      // Silent — router guard will push to /login when customerId is empty
      error.value = null
    } finally {
      loading.value = false
    }
  }

  function clear () {
    email.value = ''
    customerId.value = ''
    customerName.value = ''
    error.value = null
  }

  return { email, customerId, customerName, loading, error, init, hydrateFromToken, clear }
})
