/**
 * Wizard Ping Animation
 * 
 * Applies a "lift" animation (single grow+shrink + shadow pulse) to DOM elements
 * to draw the user's attention to the relevant section for each wizard step.
 * Uses the Web Animations API (no CSS needed, immune to WP admin overrides).
 * 
 * Only pings Card elements (`.bg-white.rounded-xl.shadow-card.border.border-gray-100`).
 * 
 * @package BoostBot
 */

/**
 * Describes a single ping target for a wizard step.
 */
export interface PingTarget {
  /** CSS selector to find the element(s) */
  selector: string
  /** Delay before pinging (ms). Default: 1200 */
  delay?: number
  /** If true, ping each matching element sequentially with staggered delays */
  sequential?: boolean
  /** Delay between sequential pings (ms). Default: 400 */
  staggerDelay?: number
}

/** The primary accent color in rgba for the shadow glow */
const GLOW = 'rgba(59, 194, 208,'

/** Duration of a single ping animation (ms) */
const PING_DURATION = 2000

/** CSS class selector that identifies a Card element */
const CARD_SELECTOR = '.bg-white.rounded-xl.shadow-card.border.border-gray-100'

/**
 * Apply a single "ping" animation to a DOM element.
 * Effect: one smooth scale-up with teal shadow glow, then back to normal.
 */
function animateElement(element: HTMLElement): void {
  element.animate([
    {
      transform: 'scale(1)',
      boxShadow: `0 0 0 0 ${GLOW} 0), 0 0 0 0 ${GLOW} 0)`,
      offset: 0,
    },
    {
      transform: 'scale(1.015)',
      boxShadow: `0 8px 30px -4px ${GLOW} 0.45), 0 0 0 3px ${GLOW} 0.18)`,
      offset: 0.4,
    },
    {
      transform: 'scale(1)',
      boxShadow: `0 0 0 0 ${GLOW} 0), 0 0 0 0 ${GLOW} 0)`,
      offset: 1,
    },
  ], {
    duration: PING_DURATION,
    easing: 'ease-in-out',
  })
}

/**
 * Calculate the total duration of a single ping pass for a target (ms).
 */
function getTargetDuration(target: PingTarget, elementCount: number): number {
  if (target.sequential && elementCount > 1) {
    return (elementCount - 1) * (target.staggerDelay ?? 400) + PING_DURATION
  }
  return PING_DURATION
}

/**
 * Find and animate elements matching a PingTarget.
 * No auto-scroll — the user stays where they are.
 * Retries up to 4 times (every 500ms) if elements aren't found yet
 * (handles pages with async loading states).
 *
 * Returns the total duration of the ping sequence (ms) for chaining.
 */
function executePing(target: PingTarget, retriesLeft = 4): number {
  const elements = document.querySelectorAll<HTMLElement>(target.selector)
  if (elements.length === 0) {
    if (retriesLeft > 0) {
      setTimeout(() => executePing(target, retriesLeft - 1), 500)
    }
    return 0
  }

  if (target.sequential && elements.length > 1) {
    elements.forEach((el, i) => {
      setTimeout(() => animateElement(el), i * (target.staggerDelay ?? 400))
    })
  } else {
    animateElement(elements[0])
  }

  return getTargetDuration(target, elements.length)
}

/**
 * Run a single pass of all ping targets.
 * Returns an estimate of when the entire pass finishes (ms from now).
 */
function runPingPass(targets: PingTarget[], baseDelay: number): number {
  let latestEnd = 0

  targets.forEach(target => {
    const delay = baseDelay + (target.delay ?? 0)
    setTimeout(() => {
      const duration = executePing(target)
      // Track when this target's animation ends (approximate for retry cases)
      const end = delay + duration
      if (end > latestEnd) latestEnd = end
    }, delay)
    // Estimate end time (assume elements are found immediately)
    const estimatedEnd = delay + PING_DURATION + (target.sequential ? 3 * (target.staggerDelay ?? 400) : 0)
    if (estimatedEnd > latestEnd) latestEnd = estimatedEnd
  })

  return latestEnd
}

/**
 * Execute all ping targets for a wizard step — runs the sequence TWICE.
 * First pass uses each target's configured delay (default 1200ms).
 * Second pass starts 1 second after the first pass finishes.
 */
export function executePingTargets(targets: PingTarget[]): void {
  if (!targets || targets.length === 0) return

  // First pass
  const firstPassEnd = runPingPass(targets, 0)

  // Second pass — 1 second after first pass completes
  const secondPassStart = firstPassEnd + 1000
  runPingPass(targets, secondPassStart)
}

/**
 * Execute all ping targets INSTANTLY (no initial delay).
 * Used by the re-ping button — still runs the double sequence.
 */
export function executePingTargetsInstant(targets: PingTarget[]): void {
  if (!targets || targets.length === 0) return

  // Create copies with delay stripped to 0
  const instantTargets = targets.map(t => ({ ...t, delay: 0 }))

  // First pass — immediate
  const firstPassEnd = runPingPass(instantTargets, 0)

  // Second pass — 1 second after first pass completes
  const secondPassStart = firstPassEnd + 1000
  runPingPass(instantTargets, secondPassStart)
}

/**
 * Ping target definitions for each wizard step ID.
 * Maps step IDs to the elements that should be highlighted.
 *
 * Strategy:
 * - Use data-wizard-id attributes on Cards for targeted pinging.
 * - For pages with multiple relevant cards, ping sequentially.
 * - Delay allows the page content to fully render after navigation.
 */
export const STEP_PING_TARGETS: Record<string, PingTarget[]> = {
  // Phase 1: Enable bot → Settings page → general settings card
  enable_bot: [
    { selector: '[data-wizard-id="general-settings"]', delay: 1200 },
  ],

  // Phase 2: Bots overview → highlight the default bot card
  bots_overview: [
    { selector: '[data-wizard-id="bot-default"]', delay: 1200 },
  ],

  // Phase 3: Basic details → first ping the tab Card, then input fields inside it
  basic_details: [
    { selector: '[data-wizard-id="bot-tab-content"]', delay: 1200 },
    {
      selector: '[data-wizard-id="bot-tab-content"] input, [data-wizard-id="bot-tab-content"] textarea, [data-wizard-id="bot-tab-content"] select',
      delay: 2400,
      sequential: true,
      staggerDelay: 300,
    },
  ],

  // Phase 4–8: Bot tabs → ping the tab's Card
  display_conditions: [
    { selector: '[data-wizard-id="bot-tab-content"]', delay: 1200 },
  ],
  appearance: [
    { selector: '[data-wizard-id="bot-tab-content"] ' + CARD_SELECTOR, delay: 1200, sequential: true, staggerDelay: 400 },
  ],
  opening_message: [
    { selector: '[data-wizard-id="bot-tab-content"] ' + CARD_SELECTOR, delay: 1200, sequential: true, staggerDelay: 400 },
  ],
  behavior: [
    { selector: '[data-wizard-id="bot-tab-content"] ' + CARD_SELECTOR, delay: 1200, sequential: true, staggerDelay: 400 },
  ],
  widgets: [
    { selector: '[data-wizard-id="bot-tab-content"]', delay: 1200 },
  ],

  // Phase 9: Knowledge base → all cards on the page
  knowledge_base: [
    { selector: '[data-wizard-id="knowledge-base-content"] ' + CARD_SELECTOR, delay: 1200, sequential: true, staggerDelay: 400 },
  ],

  // Phase 10: Brand card → all cards on the page
  business_card: [
    { selector: '[data-wizard-id="brand-card-content"] ' + CARD_SELECTOR, delay: 1200, sequential: true, staggerDelay: 400 },
  ],

  // Phase 11: Integrations → all cards on the page
  integrations: [
    { selector: '[data-wizard-id="integrations-content"] ' + CARD_SELECTOR, delay: 1200, sequential: true, staggerDelay: 400 },
  ],

  // Phase 12: Global rules → the global rules accordion card
  global_rules: [
    { selector: '[data-wizard-id="global-rules"]', delay: 1200 },
  ],

  // Phase 13: Global appearance colors → the global values accordion card
  global_appearance_colors: [
    { selector: '[data-wizard-id="global-values"]', delay: 1200 },
  ],

  // Phase 14: Global appearance typography → same accordion card
  global_appearance_typography: [
    { selector: '[data-wizard-id="global-values"]', delay: 1200 },
  ],

  // Phase 15: General settings → ping general-settings card then message-limits card
  general_settings: [
    { selector: '[data-wizard-id="general-settings"]', delay: 1200 },
    { selector: '[data-wizard-id="message-limits"]', delay: 2200 },
  ],

  // Phase 16: Credits → all cards on usage page
  credits: [
    { selector: '[data-wizard-id="credits-content"] ' + CARD_SELECTOR, delay: 1200, sequential: true, staggerDelay: 400 },
  ],

  // Phase 17: Conversations preview → all cards
  conversations_preview: [
    { selector: '[data-wizard-id="conversations-content"] ' + CARD_SELECTOR, delay: 1200, sequential: true, staggerDelay: 400 },
  ],

  // Phase 18: Finish → wizard section card
  finish: [
    { selector: '[data-wizard-id="wizard-section"]', delay: 1200 },
  ],
}
