/**
 * OnboardingGuide Component
 *
 * Interactive step-by-step guide that introduces users to the Price Builder.
 * Shows on first visit and can be dismissed at any time.
 */

import { useEffect, useRef, useCallback } from "react";
import { motion, AnimatePresence } from "motion/react";
import { Cross2Icon, ArrowRightIcon, ArrowLeftIcon, RocketIcon } from "@radix-ui/react-icons";
import { useOnboardingStore, useIsOnboardingActive, useCurrentOnboardingStep, useOnboardingProgress } from "@/stores/onboardingStore";

interface OnboardingGuideProps {
  /** Callback when user clicks to add an element during onboarding */
  onAddElement?: () => void;
}

/**
 * Scroll an element into view within the sidebar
 */
function scrollToElement(selector: string) {
  const element = document.querySelector(selector);
  if (element) {
    // Find the scrollable sidebar container
    const sidebar = element.closest(".oppb-sidebar-left");
    if (sidebar) {
      const elementRect = element.getBoundingClientRect();
      const sidebarRect = sidebar.getBoundingClientRect();

      // Calculate if element is out of view
      if (elementRect.top < sidebarRect.top || elementRect.bottom > sidebarRect.bottom) {
        element.scrollIntoView({ behavior: "smooth", block: "center" });
      }
    } else {
      element.scrollIntoView({ behavior: "smooth", block: "center" });
    }
  }
}

/**
 * Get position styles for the tooltip based on target element
 */
function getTooltipPosition(
  targetSelector: string | undefined,
  position: "top" | "bottom" | "left" | "right" | "center" = "center"
): React.CSSProperties {
  if (!targetSelector || position === "center") {
    return {
      position: "fixed",
      top: "50%",
      left: "50%",
      transform: "translate(-50%, -50%)",
    };
  }

  const target = document.querySelector(targetSelector);
  if (!target) {
    return {
      position: "fixed",
      top: "50%",
      left: "50%",
      transform: "translate(-50%, -50%)",
    };
  }

  const rect = target.getBoundingClientRect();
  const margin = 16;

  switch (position) {
    case "top":
      return {
        position: "fixed",
        bottom: `${window.innerHeight - rect.top + margin}px`,
        left: `${rect.left + rect.width / 2}px`,
        transform: "translateX(-50%)",
      };
    case "bottom":
      return {
        position: "fixed",
        top: `${rect.bottom + margin}px`,
        left: `${rect.left + rect.width / 2}px`,
        transform: "translateX(-50%)",
      };
    case "left":
      return {
        position: "fixed",
        top: `${rect.top + rect.height / 2}px`,
        right: `${window.innerWidth - rect.left + margin}px`,
        transform: "translateY(-50%)",
      };
    case "right":
      return {
        position: "fixed",
        top: `${rect.top + rect.height / 2}px`,
        left: `${rect.right + margin}px`,
        transform: "translateY(-50%)",
      };
    default:
      return {
        position: "fixed",
        top: "50%",
        left: "50%",
        transform: "translate(-50%, -50%)",
      };
  }
}

export function OnboardingGuide({ onAddElement }: OnboardingGuideProps) {
  const isActive = useIsOnboardingActive();
  const currentStep = useCurrentOnboardingStep();
  const progress = useOnboardingProgress();
  const { nextStep, previousStep, skipOnboarding, completeOnboarding, startOnboarding } = useOnboardingStore();
  const tooltipRef = useRef<HTMLDivElement>(null);
  const completed = useOnboardingStore((state) => state.completed);
  const showOnFirstVisit = useOnboardingStore((state) => state.showOnFirstVisit);

  // Auto-start onboarding on first visit
  useEffect(() => {
    if (!completed && showOnFirstVisit && !isActive) {
      // Small delay to ensure UI is rendered
      const timer = setTimeout(() => {
        startOnboarding();
      }, 500);
      return () => clearTimeout(timer);
    }
  }, [completed, showOnFirstVisit, isActive, startOnboarding]);

  // Update tooltip position function
  const updateTooltipPosition = useCallback(() => {
    if (isActive && currentStep && tooltipRef.current) {
      const position = getTooltipPosition(currentStep.target, currentStep.position);
      Object.assign(tooltipRef.current.style, position);
    }
  }, [isActive, currentStep]);

  // Scroll to target element when step changes
  useEffect(() => {
    if (isActive && currentStep?.scrollTarget) {
      // Small delay to ensure step change is processed
      setTimeout(() => {
        scrollToElement(currentStep.scrollTarget!);
        // Update position after scroll animation completes
        setTimeout(() => {
          updateTooltipPosition();
        }, 400);
      }, 100);
    }
  }, [isActive, currentStep, updateTooltipPosition]);

  // Update tooltip position when step changes (initial)
  useEffect(() => {
    updateTooltipPosition();
  }, [updateTooltipPosition]);

  // Update tooltip position on scroll/resize
  useEffect(() => {
    if (!isActive) return;

    const handleScrollOrResize = () => {
      updateTooltipPosition();
    };

    window.addEventListener("scroll", handleScrollOrResize, true);
    window.addEventListener("resize", handleScrollOrResize);

    return () => {
      window.removeEventListener("scroll", handleScrollOrResize, true);
      window.removeEventListener("resize", handleScrollOrResize);
    };
  }, [isActive, updateTooltipPosition]);

  const handleNext = useCallback(() => {
    if (currentStep?.action === "add-element") {
      // Trigger adding element callback
      onAddElement?.();
      // Move to next step after element is added
      setTimeout(() => {
        nextStep();
      }, 300);
    } else if (currentStep?.action === "complete") {
      completeOnboarding();
    } else {
      nextStep();
    }
  }, [currentStep, nextStep, completeOnboarding, onAddElement]);

  if (!isActive || !currentStep) return null;

  const isFirstStep = progress.current === 1;
  const isLastStep = progress.current === progress.total;
  const isAddElementStep = currentStep.action === "add-element";

  return (
    <AnimatePresence>
      {/* Overlay */}
      <motion.div
        className="oppb-onboarding-overlay"
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
        onClick={(e) => {
          // Only close if clicking directly on overlay, not children
          if (e.target === e.currentTarget) {
            // Don't close on overlay click - user must use buttons
          }
        }}
      />

      {/* Highlight box for target element */}
      {currentStep.target && currentStep.position !== "center" && <HighlightBox target={currentStep.target} />}

      {/* Tooltip */}
      <motion.div
        ref={tooltipRef}
        className="oppb-onboarding-tooltip"
        style={getTooltipPosition(currentStep.target, currentStep.position)}
        initial={{ opacity: 0, scale: 0.9 }}
        animate={{ opacity: 1, scale: 1 }}
        exit={{ opacity: 0, scale: 0.9 }}
        transition={{ type: "spring", stiffness: 300, damping: 25 }}
      >
        {/* Header */}
        <div className="oppb-onboarding-tooltip__header">
          <div className="oppb-onboarding-tooltip__icon">
            <RocketIcon className="w-5 h-5" />
          </div>
          <h3 className="oppb-onboarding-tooltip__title">{currentStep.title}</h3>
          <button type="button" className="oppb-onboarding-tooltip__close" onClick={skipOnboarding} aria-label="Skip tour">
            <Cross2Icon className="w-4 h-4" />
          </button>
        </div>

        {/* Content */}
        <div className="oppb-onboarding-tooltip__content">
          <p>{currentStep.description}</p>
        </div>

        {/* Footer */}
        <div className="oppb-onboarding-tooltip__footer">
          {/* Progress indicator */}
          <div className="oppb-onboarding-tooltip__progress">
            <span className="oppb-onboarding-tooltip__progress-text">
              {progress.current} of {progress.total}
            </span>
            <div className="oppb-onboarding-tooltip__progress-bar">
              <div className="oppb-onboarding-tooltip__progress-fill" style={{ width: `${progress.percentage}%` }} />
            </div>
          </div>

          {/* Navigation buttons */}
          <div className="oppb-onboarding-tooltip__actions">
            {!isFirstStep && (
              <button type="button" className="oppb-onboarding-tooltip__btn oppb-onboarding-tooltip__btn--secondary" onClick={previousStep}>
                <ArrowLeftIcon className="w-4 h-4" />
                Back
              </button>
            )}
            <button type="button" className="oppb-onboarding-tooltip__btn oppb-onboarding-tooltip__btn--primary" onClick={handleNext}>
              {isLastStep ? (
                "Finish Tour"
              ) : isAddElementStep ? (
                <>
                  Add Regular Price
                  <ArrowRightIcon className="w-4 h-4" />
                </>
              ) : (
                <>
                  Next
                  <ArrowRightIcon className="w-4 h-4" />
                </>
              )}
            </button>
          </div>
        </div>
      </motion.div>
    </AnimatePresence>
  );
}

/**
 * Highlight box component that appears around target elements
 */
function HighlightBox({ target }: { target: string }) {
  const boxRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const updatePosition = () => {
      const element = document.querySelector(target);
      if (element && boxRef.current) {
        const rect = element.getBoundingClientRect();
        const padding = 4;
        boxRef.current.style.top = `${rect.top - padding}px`;
        boxRef.current.style.left = `${rect.left - padding}px`;
        boxRef.current.style.width = `${rect.width + padding * 2}px`;
        boxRef.current.style.height = `${rect.height + padding * 2}px`;
      }
    };

    updatePosition();

    // Update position on scroll or resize
    window.addEventListener("scroll", updatePosition, true);
    window.addEventListener("resize", updatePosition);

    return () => {
      window.removeEventListener("scroll", updatePosition, true);
      window.removeEventListener("resize", updatePosition);
    };
  }, [target]);

  return (
    <motion.div ref={boxRef} className="oppb-onboarding-highlight" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} />
  );
}

export default OnboardingGuide;
