import React, { forwardRef } from 'react';
import { clsx } from 'clsx';
import { useLocation, Link } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { getBreadcrumbs, getRouteByPath } from '../../../router/routes.config';
import { 
  ChevronRight, 
  Home, 
  MoreHorizontal,
  ExternalLink 
} from 'lucide-react';

export interface BreadcrumbItem {
  label: string;
  path: string;
  icon?: React.ComponentType<{ className?: string }>;
  disabled?: boolean;
  external?: boolean;
}

export interface BreadcrumbsProps {
  className?: string;
  /**
   * Custom breadcrumb items (overrides auto-generated ones)
   */
  items?: BreadcrumbItem[];
  /**
   * Show home icon on first item
   */
  showHome?: boolean;
  /**
   * Home path (defaults to '/')
   */
  homePath?: string;
  /**
   * Home label
   */
  homeLabel?: string;
  /**
   * Custom separator component
   */
  separator?: React.ReactNode;
  /**
   * Maximum number of items to show before truncating
   */
  maxItems?: number;
  /**
   * Show truncation in the middle (true) or at the beginning (false)
   */
  truncateMiddle?: boolean;
  /**
   * Custom truncation component
   */
  truncationComponent?: React.ReactNode;
  /**
   * Custom link component for external handling
   */
  linkComponent?: React.ComponentType<{ 
    to: string; 
    className?: string; 
    children: React.ReactNode;
    external?: boolean;
  }>;
  /**
   * Hide breadcrumbs for certain paths
   */
  hiddenPaths?: string[];
  /**
   * Custom item renderer
   */
  itemRenderer?: (item: BreadcrumbItem, index: number, isLast: boolean) => React.ReactNode;
}

export interface BreadcrumbsRef {
  scrollToEnd: () => void;
  getCurrentPath: () => string;
}

/**
 * Breadcrumbs - Breadcrumb navigation component with links and separators
 * 
 * Features:
 * - Auto-generate breadcrumbs from current route path
 * - Clickable navigation links with proper hover states
 * - Custom separators with good visual hierarchy
 * - Truncation for long paths with smart middle/start truncation
 * - Home icon and custom icons support
 * - External link handling with indicators
 * - Keyboard navigation support
 * - Responsive design with mobile adaptations
 * - Custom renderers for advanced use cases
 */
export const Breadcrumbs = forwardRef<BreadcrumbsRef, BreadcrumbsProps>(({
  className,
  items: customItems,
  showHome = true,
  homePath = '/',
  homeLabel,
  separator,
  maxItems = 5,
  truncateMiddle = true,
  truncationComponent,
  linkComponent: CustomLink,
  hiddenPaths = [],
  itemRenderer,
}, ref) => {
  const { t } = useTranslation();
  const location = useLocation();
  const containerRef = React.useRef<HTMLDivElement>(null);

  // Set default home label if not provided
  const resolvedHomeLabel = homeLabel || t('common:breadcrumbs.home', 'Inicio');

  // Get breadcrumbs from router config or use custom items
  const routeBreadcrumbs = getBreadcrumbs(location.pathname);
  
  const generateItems = (): BreadcrumbItem[] => {
    if (customItems) {
      return customItems;
    }

    const items: BreadcrumbItem[] = [];

    // Add home if enabled
    if (showHome && location.pathname !== homePath) {
      items.push({
        label: resolvedHomeLabel,
        path: homePath,
        icon: Home,
      });
    }

    // Add route breadcrumbs
    routeBreadcrumbs.forEach(route => {
      // Use breadcrumbTitle if available, otherwise use title
      const label = route.meta?.breadcrumbTitle || route.title;
      
      items.push({
        label,
        path: route.path,
        disabled: route.path === location.pathname, // Current page is disabled
      });
    });

    return items;
  };

  const allItems = generateItems();

  // Filter out hidden paths
  const visibleItems = allItems.filter(item => !hiddenPaths.includes(item.path));

  // Handle truncation
  const getTruncatedItems = (): BreadcrumbItem[] => {
    if (visibleItems.length <= maxItems) {
      return visibleItems;
    }

    if (truncateMiddle && visibleItems.length > 3) {
      // Keep first, last, and some middle items
      const first = visibleItems[0];
      const last = visibleItems[visibleItems.length - 1];
      const secondToLast = visibleItems[visibleItems.length - 2];
      
      return [first, { label: '...', path: '', disabled: true }, secondToLast, last];
    } else {
      // Keep last maxItems
      return [
        { label: '...', path: '', disabled: true },
        ...visibleItems.slice(-(maxItems - 1))
      ];
    }
  };

  const displayItems = getTruncatedItems();

  // Scroll to end
  const scrollToEnd = React.useCallback(() => {
    if (containerRef.current) {
      containerRef.current.scrollTo({
        left: containerRef.current.scrollWidth,
        behavior: 'smooth'
      });
    }
  }, []);

  // Get current path
  const getCurrentPath = React.useCallback(() => {
    return location.pathname;
  }, [location.pathname]);

  // Expose ref methods
  React.useImperativeHandle(ref, () => ({
    scrollToEnd,
    getCurrentPath,
  }), [scrollToEnd, getCurrentPath]);

  // Auto-scroll to end when items change
  React.useEffect(() => {
    scrollToEnd();
  }, [scrollToEnd, displayItems.length]);

  // Default separator
  const defaultSeparator = (
    <ChevronRight className="w-4 h-4 text-[var(--text-tertiary)] flex-shrink-0" />
  );

  // Default truncation component
  const defaultTruncationComponent = (
    <div className="flex items-center gap-1 px-2 py-1 text-[var(--text-tertiary)]">
      <MoreHorizontal className="w-4 h-4" />
    </div>
  );

  // Default link component
  const DefaultLink: React.FC<{
    to: string;
    className?: string;
    children: React.ReactNode;
    external?: boolean;
  }> = ({ to, className, children, external }) => {
    if (external) {
      return (
        <a
          href={to}
          target="_blank"
          rel="noopener noreferrer"
          className={className}
        >
          {children}
        </a>
      );
    }
    
    return (
      <Link to={to} className={className}>
        {children}
      </Link>
    );
  };

  const LinkComponent = CustomLink || DefaultLink;

  // Render single item
  const renderItem = (item: BreadcrumbItem, index: number, isLast: boolean) => {
    if (itemRenderer) {
      return itemRenderer(item, index, isLast);
    }

    const ItemIcon = item.icon;
    
    // Handle truncation item
    if (item.label === '...') {
      return (
        <li key={`truncation-${index}`} className="flex items-center">
          {truncationComponent || defaultTruncationComponent}
        </li>
      );
    }

    const content = (
      <div className="flex items-center gap-2 min-w-0">
        {ItemIcon && (
          <ItemIcon className="w-4 h-4 text-[var(--text-tertiary)] flex-shrink-0" />
        )}
        <span className={clsx(
          'truncate transition-colors duration-200',
          isLast 
            ? 'text-[var(--text-primary)] font-medium'
            : 'text-[var(--text-secondary)]'
        )}>
          {item.label}
        </span>
        {item.external && (
          <ExternalLink className="w-3 h-3 text-[var(--text-tertiary)] flex-shrink-0" />
        )}
      </div>
    );

    return (
      <li key={item.path || index} className="flex items-center min-w-0">
        {item.disabled || isLast ? (
          <span className="flex items-center gap-2 px-2 py-1 min-w-0">
            {content}
          </span>
        ) : (
          <LinkComponent
            to={item.path}
            external={item.external}
            className={clsx(
              'flex items-center gap-2 px-2 py-1 rounded-md min-w-0',
              'transition-colors duration-200',
              'hover:bg-[var(--bg-secondary)] hover:text-[var(--text-primary)]',
              'focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]/20',
              'focus:bg-[var(--bg-secondary)]'
            )}
          >
            {content}
          </LinkComponent>
        )}
      </li>
    );
  };

  // Don't render if no items or path is hidden
  if (displayItems.length === 0 || hiddenPaths.includes(location.pathname)) {
    return null;
  }

  return (
    <nav
      ref={containerRef}
      className={clsx(
        'flex items-center gap-1 text-sm overflow-x-auto',
        'scrollbar-none pb-1', // Hide scrollbar but allow scrolling
        className
      )}
      aria-label="Breadcrumb"
      role="navigation"
    >
      <ol className="flex items-center gap-1 min-w-0 flex-nowrap">
        {displayItems.map((item, index) => {
          const isLast = index === displayItems.length - 1;
          
          return (
            <React.Fragment key={item.path || index}>
              {renderItem(item, index, isLast)}
              
              {!isLast && (
                <li className="flex items-center flex-shrink-0 mx-1" aria-hidden="true">
                  {separator || defaultSeparator}
                </li>
              )}
            </React.Fragment>
          );
        })}
      </ol>
    </nav>
  );
});

Breadcrumbs.displayName = 'Breadcrumbs';