import { useCallback, useEffect, useMemo, useState } from 'react';

/**
 * Minimal page interface for navigation
 */
export interface NavigablePage {
  id: string;
  sort_order?: number;
  slug?: string;
}

export interface UsePageNavigationOptions<TPage extends NavigablePage> {
  pages: TPage[];
  defaultPageId?: string;
  trackHistory?: boolean;
  onPageChange?: (pageId: string, isBack: boolean) => void;
}

export interface UsePageNavigationResult<TPage extends NavigablePage> {
  currentPageId: string | null;
  currentPage: TPage | null;
  pageHistory: string[];
  previousPageId: string | null;
  defaultPage: TPage | null;
  setCurrentPageId: (pageId: string) => void;
  applyPageSelection: (targetPageId: string, isBack?: boolean) => void;
  isBackNavigation: (targetPageId: string) => boolean;
  goBack: () => boolean;
  resetHistory: () => void;
}

/**
 * Hook for managing page navigation state with optional history tracking.
 * Default page is the first page by sort_order.
 *
 * @example
 * // Basic usage (runtime)
 * const nav = usePageNavigation({
 *   pages,
 *   trackHistory: true,
 * });
 *
 * // Editor usage (constructor) - no history
 * const nav = usePageNavigation({
 *   pages,
 *   defaultPageId: initialPageId,
 *   trackHistory: false,
 * });
 */
export function usePageNavigation<TPage extends NavigablePage>(
  options: UsePageNavigationOptions<TPage>,
): UsePageNavigationResult<TPage> {
  const { pages, defaultPageId, trackHistory = true, onPageChange } = options;

  const [currentPageId, setCurrentPageIdState] = useState<string | null>(null);
  const [pageHistory, setPageHistory] = useState<string[]>([]);

  // Compute default page (by ID or first by sort order)
  const defaultPage = useMemo(() => {
    if (!pages.length) return null;

    // Try explicit default page ID
    if (defaultPageId) {
      const byId = pages.find((p) => p.id === defaultPageId);
      if (byId) return byId;
    }

    // Fall back to first by sort order
    return [...pages].sort(
      (a, b) => (a.sort_order || 0) - (b.sort_order || 0),
    )[0];
  }, [pages, defaultPageId]);

  // Get current page object
  const currentPage = useMemo(() => {
    if (!pages.length) return null;
    if (currentPageId) {
      return pages.find((p) => p.id === currentPageId) || null;
    }
    return defaultPage;
  }, [pages, currentPageId, defaultPage]);

  // Previous page ID from history
  const previousPageId = useMemo(() => {
    if (pageHistory.length < 2) return null;
    return pageHistory[pageHistory.length - 2];
  }, [pageHistory]);

  // Check if navigating to a page would be a "back" navigation
  const isBackNavigation = useCallback(
    (targetPageId: string): boolean => {
      return previousPageId === targetPageId;
    },
    [previousPageId],
  );

  // Apply page selection with history tracking
  const applyPageSelection = useCallback(
    (targetPageId: string, isBack = false) => {
      setCurrentPageIdState(targetPageId);

      if (trackHistory) {
        setPageHistory((prev) => {
          if (!prev.length) return [targetPageId];
          const currentId = prev[prev.length - 1];
          if (currentId === targetPageId) return prev;

          // If going back and target matches previous, pop history
          if (
            isBack &&
            prev.length > 1 &&
            prev[prev.length - 2] === targetPageId
          ) {
            return prev.slice(0, -1);
          }

          return [...prev, targetPageId];
        });
      }

      onPageChange?.(targetPageId, isBack);
    },
    [trackHistory, onPageChange],
  );

  // Simple setter (no history tracking)
  const setCurrentPageId = useCallback(
    (pageId: string) => {
      setCurrentPageIdState(pageId);
      if (trackHistory && pageHistory.length === 0) {
        setPageHistory([pageId]);
      }
    },
    [trackHistory, pageHistory.length],
  );

  // Go back in history
  const goBack = useCallback((): boolean => {
    if (!trackHistory || pageHistory.length < 2) return false;
    const targetPageId = pageHistory[pageHistory.length - 2];
    applyPageSelection(targetPageId, true);
    return true;
  }, [trackHistory, pageHistory, applyPageSelection]);

  // Reset history
  const resetHistory = useCallback(() => {
    setPageHistory(currentPageId ? [currentPageId] : []);
  }, [currentPageId]);

  // Initialize to default page
  useEffect(() => {
    if (defaultPage?.id && !currentPageId) {
      setCurrentPageIdState(defaultPage.id);
      if (trackHistory) {
        setPageHistory((prev) => (prev.length ? prev : [defaultPage.id]));
      }
    }
  }, [defaultPage, currentPageId, trackHistory]);

  return {
    currentPageId,
    currentPage,
    pageHistory,
    previousPageId,
    defaultPage,
    setCurrentPageId,
    applyPageSelection,
    isBackNavigation,
    goBack,
    resetHistory,
  };
}
