import { useState, createContext, useContext, type ReactNode } from 'react';
import { Link, useLocation } from 'react-router-dom';
import { motion, AnimatePresence } from 'framer-motion';
import { ChevronDown } from 'lucide-react';
import { cn } from '@utils/cn';

// Context for sidebar state
interface SidebarContextValue {
  collapsed: boolean;
  setCollapsed: (collapsed: boolean) => void;
}

const SidebarContext = createContext<SidebarContextValue | null>(null);

export function useSidebar() {
  const context = useContext(SidebarContext);
  if (!context) {
    throw new Error('Sidebar components must be used within a Sidebar provider');
  }
  return context;
}

// Main Sidebar component
export interface SidebarProps {
  children: ReactNode;
  collapsed?: boolean;
  onCollapsedChange?: (collapsed: boolean) => void;
  className?: string;
}

export function Sidebar({
  children,
  collapsed: controlledCollapsed,
  onCollapsedChange,
  className,
}: SidebarProps) {
  const [internalCollapsed, setInternalCollapsed] = useState(false);
  const collapsed = controlledCollapsed ?? internalCollapsed;

  const setCollapsed = (value: boolean) => {
    setInternalCollapsed(value);
    onCollapsedChange?.(value);
  };

  return (
    <SidebarContext.Provider value={{ collapsed, setCollapsed }}>
      <aside
        className={cn(
          'flex h-full flex-col bg-white transition-all duration-300',
          collapsed ? 'w-16' : 'w-64',
          className
        )}
      >
        {children}
      </aside>
    </SidebarContext.Provider>
  );
}

// Sidebar Header
export interface SidebarHeaderProps {
  children: ReactNode;
  className?: string;
}

export function SidebarHeader({ children, className }: SidebarHeaderProps) {
  const { collapsed } = useSidebar();

  return (
    <div
      className={cn(
        'flex h-16 items-center border-b px-4',
        collapsed && 'justify-center px-2',
        className
      )}
    >
      {children}
    </div>
  );
}

// Sidebar Content (scrollable)
export interface SidebarContentProps {
  children: ReactNode;
  className?: string;
}

export function SidebarContent({ children, className }: SidebarContentProps) {
  return (
    <div className={cn('flex-1 overflow-y-auto p-2', className)}>
      {children}
    </div>
  );
}

// Sidebar Footer
export interface SidebarFooterProps {
  children: ReactNode;
  className?: string;
}

export function SidebarFooter({ children, className }: SidebarFooterProps) {
  return (
    <div className={cn('border-t p-4', className)}>
      {children}
    </div>
  );
}

// Sidebar Section (group of items)
export interface SidebarSectionProps {
  title?: string;
  children: ReactNode;
  className?: string;
}

export function SidebarSection({ title, children, className }: SidebarSectionProps) {
  const { collapsed } = useSidebar();

  return (
    <div className={cn('mb-4', className)}>
      {title && !collapsed && (
        <div className="mb-2 px-3 text-xs font-semibold uppercase tracking-wider text-gray-400">
          {title}
        </div>
      )}
      <nav className="space-y-1">{children}</nav>
    </div>
  );
}

// Sidebar Item (navigation link)
export interface SidebarItemProps {
  href: string;
  icon?: ReactNode;
  label: string;
  badge?: string | number;
  badgeVariant?: 'default' | 'primary' | 'danger';
  disabled?: boolean;
  external?: boolean;
}

export function SidebarItem({
  href,
  icon,
  label,
  badge,
  badgeVariant = 'default',
  disabled = false,
  external = false,
}: SidebarItemProps) {
  const location = useLocation();
  const { collapsed } = useSidebar();
  const isActive = location.pathname === href || location.pathname.startsWith(`${href}/`);

  const badgeColors = {
    default: 'bg-gray-100 text-gray-600',
    primary: 'bg-primary-100 text-primary-700',
    danger: 'bg-danger-100 text-danger-700',
  };

  const content = (
    <>
      {icon && (
        <span className={cn('flex-shrink-0', isActive ? 'text-primary-600' : 'text-gray-400')}>
          {icon}
        </span>
      )}
      {!collapsed && (
        <>
          <span className="flex-1 truncate">{label}</span>
          {badge !== undefined && (
            <span
              className={cn(
                'flex-shrink-0 rounded-full px-2 py-0.5 text-xs font-medium',
                badgeColors[badgeVariant]
              )}
            >
              {badge}
            </span>
          )}
        </>
      )}
    </>
  );

  const className = cn(
    'flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-colors',
    isActive
      ? 'bg-primary-50 text-primary-700'
      : 'text-gray-700 hover:bg-gray-100',
    disabled && 'cursor-not-allowed opacity-50',
    collapsed && 'justify-center px-2'
  );

  if (disabled) {
    return <div className={className}>{content}</div>;
  }

  if (external) {
    return (
      <a href={href} target="_blank" rel="noopener noreferrer" className={className}>
        {content}
      </a>
    );
  }

  return (
    <Link to={href} className={className}>
      {content}
    </Link>
  );
}

// Sidebar Submenu (collapsible group)
export interface SidebarSubmenuProps {
  icon?: ReactNode;
  label: string;
  children: ReactNode;
  defaultOpen?: boolean;
}

export function SidebarSubmenu({
  icon,
  label,
  children,
  defaultOpen = false,
}: SidebarSubmenuProps) {
  const [isOpen, setIsOpen] = useState(defaultOpen);
  const { collapsed } = useSidebar();

  if (collapsed) {
    return (
      <div className="relative group">
        <button
          className="flex w-full items-center justify-center rounded-lg px-2 py-2 text-gray-700 hover:bg-gray-100"
        >
          {icon && <span className="text-gray-400">{icon}</span>}
        </button>
        {/* Tooltip menu on hover when collapsed */}
        <div className="absolute left-full top-0 ml-2 hidden w-48 rounded-lg border bg-white py-2 shadow-lg group-hover:block">
          <div className="px-3 py-2 text-sm font-medium text-gray-900">{label}</div>
          {children}
        </div>
      </div>
    );
  }

  return (
    <div>
      <button
        onClick={() => setIsOpen(!isOpen)}
        className="flex w-full items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100"
      >
        {icon && <span className="text-gray-400">{icon}</span>}
        <span className="flex-1 text-left">{label}</span>
        <motion.span
          animate={{ rotate: isOpen ? 180 : 0 }}
          transition={{ duration: 0.2 }}
        >
          <ChevronDown className="h-4 w-4 text-gray-400" />
        </motion.span>
      </button>
      <AnimatePresence initial={false}>
        {isOpen && (
          <motion.div
            initial={{ height: 0, opacity: 0 }}
            animate={{ height: 'auto', opacity: 1 }}
            exit={{ height: 0, opacity: 0 }}
            transition={{ duration: 0.2 }}
            className="overflow-hidden"
          >
            <div className="ml-4 mt-1 space-y-1 border-l pl-4">
              {children}
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}

// Sidebar Divider
export function SidebarDivider() {
  return <div className="my-2 border-t" />;
}
