import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import type { Mock } from 'vitest';

import { usePage } from '@inertiajs/react';

import { TooltipProvider } from '@/Components/ui/tooltip';

import SiteNav from './SiteNav';

// Mock Inertia Link component to avoid URL errors
vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    Link: ({
      href,
      className,
      children,
    }: {
      href: string;
      className?: string;
      children: React.ReactNode;
    }) => (
      <a href={href} className={className}>
        {children}
      </a>
    ),
    usePage: vi.fn(() => ({
      props: {
        auth: { user: null },
        errors: {},
        flash: {},
      },
      url: '/sites/1/onboarding',
      component: 'Onboarding/Index',
      version: null,
    })),
  };
});

// Mock the route function with SiteNav routes
const mockRoutes: Record<string, string> = {
  'onboarding.index': '/sites/:siteId/onboarding',
  'analyze.index': '/sites/:siteId/analyze',
  'recommendations.index': '/sites/:siteId/recommendations',
  'content-briefs.index': '/sites/:siteId/content-briefs',
  'cannibalization.index': '/sites/:siteId/cannibalization',
  'opportunity-map.index': '/sites/:siteId/opportunity-map',
  'geographic.index': '/sites/:siteId/geographic',
  'device.index': '/sites/:siteId/device',
  'pipeline.index': '/sites/:siteId/pipeline',
  'sites.roi.index': '/sites/:siteId/roi',
  'sites.schedule.edit': '/sites/:siteId/schedule/edit',
};

const routeFn = (name: string, params?: number | Record<string, unknown>): string => {
  const siteId =
    typeof params === 'number' ? params : (params as Record<string, unknown>)?.siteId || 1;
  const baseRoute = mockRoutes[name] || `/${name.replace(/\./g, '/')}`;
  return baseRoute.replace(':siteId', String(siteId));
};

// Override global route function
(globalThis as unknown as { route: typeof routeFn }).route = routeFn;

// Helper to render SiteNav with TooltipProvider
const renderSiteNav = (props: Parameters<typeof SiteNav>[0]) => {
  return render(
    <TooltipProvider>
      <SiteNav {...props} />
    </TooltipProvider>,
  );
};

describe('SiteNav', () => {
  const user = userEvent.setup();

  beforeEach(() => {
    // Reset mock before each test
    (usePage as Mock).mockReturnValue({
      props: {
        auth: { user: null },
        errors: {},
        flash: {},
      },
      url: '/sites/1/onboarding',
      component: 'Onboarding/Index',
      version: null,
    });
  });

  // ============================================
  // Rendering tests
  // ============================================

  describe('rendering', () => {
    it('renders navigation component', () => {
      renderSiteNav({ siteId: 1 });

      expect(screen.getByRole('navigation')).toBeInTheDocument();
    });

    it('renders all tabs', () => {
      renderSiteNav({ siteId: 1 });

      expect(screen.getByText('Connections')).toBeInTheDocument();
      expect(screen.getByText('Analyze')).toBeInTheDocument();
      expect(screen.getByText('Recommendations')).toBeInTheDocument();
      expect(screen.getByText('Cannibalization')).toBeInTheDocument();
      expect(screen.getByText('Opportunity Map')).toBeInTheDocument();
      expect(screen.getByText('Geographic')).toBeInTheDocument();
      expect(screen.getByText('Device')).toBeInTheDocument();
      expect(screen.getByText('Schedule')).toBeInTheDocument();
    });

    it('renders tab icons', () => {
      const { container } = renderSiteNav({ siteId: 1 });

      // Each tab should have an icon (lucide-react renders as svg)
      const nav = container.querySelector('nav');
      const icons = nav?.querySelectorAll('svg');
      expect(icons).toHaveLength(11);
    });

    it('renders with border bottom', () => {
      const { container } = renderSiteNav({ siteId: 1 });

      const nav = container.querySelector('nav');
      expect(nav).toHaveClass('border-b');
    });
  });

  // ============================================
  // Tab state tests (enabled/disabled)
  // ============================================

  describe('tab enabled/disabled states', () => {
    it('Connections tab is always enabled', () => {
      renderSiteNav({ siteId: 1, canAnalyze: false, canRecommend: false });

      const connectionsLink = screen.getByText('Connections').closest('a');
      expect(connectionsLink).toBeInTheDocument();
      expect(connectionsLink).toHaveAttribute('href', '/sites/1/onboarding');
    });

    it('Analyze tab is disabled by default', () => {
      renderSiteNav({ siteId: 1 });

      const analyzeTab = screen.getByText('Analyze').closest('button');
      expect(analyzeTab).toHaveClass('cursor-not-allowed');
      expect(analyzeTab).toHaveClass('text-muted-foreground/50');
    });

    it('Analyze tab is enabled when canAnalyze is true', () => {
      renderSiteNav({ siteId: 1, canAnalyze: true });

      const analyzeLink = screen.getByText('Analyze').closest('a');
      expect(analyzeLink).toBeInTheDocument();
      expect(analyzeLink).toHaveAttribute('href', '/sites/1/analyze');
    });

    it('Recommendations tab is disabled by default', () => {
      renderSiteNav({ siteId: 1 });

      const recommendationsTab = screen.getByText('Recommendations').closest('button');
      expect(recommendationsTab).toHaveClass('cursor-not-allowed');
      expect(recommendationsTab).toHaveClass('text-muted-foreground/50');
    });

    it('Recommendations tab is enabled when canRecommend is true', () => {
      renderSiteNav({ siteId: 1, canRecommend: true });

      const recommendationsLink = screen.getByText('Recommendations').closest('a');
      expect(recommendationsLink).toBeInTheDocument();
      expect(recommendationsLink).toHaveAttribute('href', '/sites/1/recommendations');
    });

    it('all tabs can be enabled simultaneously', () => {
      renderSiteNav({ siteId: 1, canAnalyze: true, canRecommend: true });

      expect(screen.getByText('Connections').closest('a')).toBeInTheDocument();
      expect(screen.getByText('Analyze').closest('a')).toBeInTheDocument();
      expect(screen.getByText('Recommendations').closest('a')).toBeInTheDocument();
    });
  });

  // ============================================
  // Tooltip tests
  // ============================================

  describe('tooltips on disabled tabs', () => {
    it('Analyze tab shows tooltip when disabled', async () => {
      renderSiteNav({ siteId: 1, canAnalyze: false });

      const analyzeTab = screen.getByText('Analyze');
      await user.hover(analyzeTab);

      const tooltip = await screen.findByRole('tooltip');
      expect(tooltip).toBeInTheDocument();
    });

    it('Analyze tooltip has correct message', async () => {
      renderSiteNav({ siteId: 1, canAnalyze: false });

      const analyzeTab = screen.getByText('Analyze');
      await user.hover(analyzeTab);

      const tooltip = await screen.findByRole('tooltip');
      expect(tooltip).toHaveTextContent('Connect Google Search Console to enable analysis');
    });

    it('Recommendations tab shows tooltip when disabled', async () => {
      renderSiteNav({ siteId: 1, canRecommend: false });

      const recommendationsTab = screen.getByText('Recommendations');
      await user.hover(recommendationsTab);

      const tooltip = await screen.findByRole('tooltip');
      expect(tooltip).toBeInTheDocument();
    });

    it('Recommendations tooltip has correct message', async () => {
      renderSiteNav({ siteId: 1, canRecommend: false });

      const recommendationsTab = screen.getByText('Recommendations');
      await user.hover(recommendationsTab);

      const tooltip = await screen.findByRole('tooltip');
      expect(tooltip).toHaveTextContent(
        'Connect Google Search Console and run an analysis to view recommendations',
      );
    });

    it('Connections tab does not show tooltip (always enabled)', async () => {
      renderSiteNav({ siteId: 1 });

      const connectionsTab = screen.getByText('Connections');
      await user.hover(connectionsTab);

      // Wait a bit to ensure tooltip doesn't appear
      await new Promise((resolve) => setTimeout(resolve, 100));

      const tooltip = screen.queryByRole('tooltip');
      expect(tooltip).not.toBeInTheDocument();
    });

    it('enabled Analyze tab does not show tooltip', async () => {
      renderSiteNav({ siteId: 1, canAnalyze: true });

      const analyzeTab = screen.getByText('Analyze');
      await user.hover(analyzeTab);

      // Wait a bit to ensure tooltip doesn't appear
      await new Promise((resolve) => setTimeout(resolve, 100));

      const tooltip = screen.queryByRole('tooltip');
      expect(tooltip).not.toBeInTheDocument();
    });

    it('enabled Recommendations tab does not show tooltip', async () => {
      renderSiteNav({ siteId: 1, canRecommend: true });

      const recommendationsTab = screen.getByText('Recommendations');
      await user.hover(recommendationsTab);

      // Wait a bit to ensure tooltip doesn't appear
      await new Promise((resolve) => setTimeout(resolve, 100));

      const tooltip = screen.queryByRole('tooltip');
      expect(tooltip).not.toBeInTheDocument();
    });
  });

  // ============================================
  // Active state tests
  // ============================================

  describe('active state based on URL', () => {
    it('Connections tab is active on onboarding page', () => {
      (usePage as Mock).mockReturnValue({
        props: { auth: { user: null }, errors: {}, flash: {} },
        url: '/sites/1/onboarding',
        component: 'Onboarding/Index',
        version: null,
      });

      renderSiteNav({ siteId: 1 });

      const connectionsLink = screen.getByText('Connections').closest('a');
      expect(connectionsLink).toHaveClass('border-primary');
      expect(connectionsLink).toHaveClass('text-foreground');
    });

    it('Analyze tab is active on analyze page', () => {
      (usePage as Mock).mockReturnValue({
        props: { auth: { user: null }, errors: {}, flash: {} },
        url: '/sites/1/analyze',
        component: 'Analyze/Index',
        version: null,
      });

      renderSiteNav({ siteId: 1, canAnalyze: true });

      const analyzeLink = screen.getByText('Analyze').closest('a');
      expect(analyzeLink).toHaveClass('border-primary');
      expect(analyzeLink).toHaveClass('text-foreground');
    });

    it('Recommendations tab is active on recommendations page', () => {
      (usePage as Mock).mockReturnValue({
        props: { auth: { user: null }, errors: {}, flash: {} },
        url: '/sites/1/recommendations',
        component: 'Recommendations/Index',
        version: null,
      });

      renderSiteNav({ siteId: 1, canRecommend: true });

      const recommendationsLink = screen.getByText('Recommendations').closest('a');
      expect(recommendationsLink).toHaveClass('border-primary');
      expect(recommendationsLink).toHaveClass('text-foreground');
    });

    it('inactive tabs have transparent border', () => {
      (usePage as Mock).mockReturnValue({
        props: { auth: { user: null }, errors: {}, flash: {} },
        url: '/sites/1/onboarding',
        component: 'Onboarding/Index',
        version: null,
      });

      renderSiteNav({ siteId: 1, canAnalyze: true, canRecommend: true });

      const analyzeLink = screen.getByText('Analyze').closest('a');
      const recommendationsLink = screen.getByText('Recommendations').closest('a');

      expect(analyzeLink).toHaveClass('border-transparent');
      expect(recommendationsLink).toHaveClass('border-transparent');
    });

    it('works with nested URLs', () => {
      (usePage as Mock).mockReturnValue({
        props: { auth: { user: null }, errors: {}, flash: {} },
        url: '/sites/1/analyze/results',
        component: 'Analyze/Results',
        version: null,
      });

      renderSiteNav({ siteId: 1, canAnalyze: true });

      const analyzeLink = screen.getByText('Analyze').closest('a');
      expect(analyzeLink).toHaveClass('border-primary');
    });
  });

  // ============================================
  // Navigation link tests
  // ============================================

  describe('navigation links', () => {
    it('Connections link has correct href', () => {
      renderSiteNav({ siteId: 1 });

      const connectionsLink = screen.getByText('Connections').closest('a');
      expect(connectionsLink).toHaveAttribute('href', '/sites/1/onboarding');
    });

    it('Analyze link has correct href when enabled', () => {
      renderSiteNav({ siteId: 1, canAnalyze: true });

      const analyzeLink = screen.getByText('Analyze').closest('a');
      expect(analyzeLink).toHaveAttribute('href', '/sites/1/analyze');
    });

    it('Recommendations link has correct href when enabled', () => {
      renderSiteNav({ siteId: 1, canRecommend: true });

      const recommendationsLink = screen.getByText('Recommendations').closest('a');
      expect(recommendationsLink).toHaveAttribute('href', '/sites/1/recommendations');
    });

    it('uses correct siteId in links', () => {
      renderSiteNav({ siteId: 42, canAnalyze: true, canRecommend: true });

      expect(screen.getByText('Connections').closest('a')).toHaveAttribute(
        'href',
        '/sites/42/onboarding',
      );
      expect(screen.getByText('Analyze').closest('a')).toHaveAttribute('href', '/sites/42/analyze');
      expect(screen.getByText('Recommendations').closest('a')).toHaveAttribute(
        'href',
        '/sites/42/recommendations',
      );
    });
  });

  // ============================================
  // Styling tests
  // ============================================

  describe('styling', () => {
    it('has navigation styling', () => {
      const { container } = renderSiteNav({ siteId: 1 });

      const nav = container.querySelector('nav');
      expect(nav).toHaveClass('flex');
      expect(nav).toHaveClass('gap-1');
      expect(nav).toHaveClass('border-b');
      expect(nav).toHaveClass('mb-6');
    });

    it('enabled tabs have correct base styling', () => {
      renderSiteNav({ siteId: 1, canAnalyze: true });

      const analyzeLink = screen.getByText('Analyze').closest('a');
      expect(analyzeLink).toHaveClass('flex');
      expect(analyzeLink).toHaveClass('items-center');
      expect(analyzeLink).toHaveClass('gap-2');
      expect(analyzeLink).toHaveClass('px-4');
      expect(analyzeLink).toHaveClass('py-3');
      expect(analyzeLink).toHaveClass('text-sm');
      expect(analyzeLink).toHaveClass('font-medium');
    });

    it('disabled tabs have correct styling', () => {
      renderSiteNav({ siteId: 1, canAnalyze: false });

      const analyzeTab = screen.getByText('Analyze').closest('button');
      expect(analyzeTab).toHaveClass('flex');
      expect(analyzeTab).toHaveClass('items-center');
      expect(analyzeTab).toHaveClass('gap-2');
      expect(analyzeTab).toHaveClass('px-4');
      expect(analyzeTab).toHaveClass('py-3');
      expect(analyzeTab).toHaveClass('text-sm');
      expect(analyzeTab).toHaveClass('font-medium');
      expect(analyzeTab).toHaveClass('text-muted-foreground/50');
      expect(analyzeTab).toHaveClass('cursor-not-allowed');
    });

    it('active tab has primary border', () => {
      (usePage as Mock).mockReturnValue({
        props: { auth: { user: null }, errors: {}, flash: {} },
        url: '/sites/1/onboarding',
        component: 'Onboarding/Index',
        version: null,
      });

      renderSiteNav({ siteId: 1 });

      const connectionsLink = screen.getByText('Connections').closest('a');
      expect(connectionsLink).toHaveClass('border-b-2');
      expect(connectionsLink).toHaveClass('border-primary');
    });

    it('inactive tab has transparent border and hover effects', () => {
      (usePage as Mock).mockReturnValue({
        props: { auth: { user: null }, errors: {}, flash: {} },
        url: '/sites/1/onboarding',
        component: 'Onboarding/Index',
        version: null,
      });

      renderSiteNav({ siteId: 1, canAnalyze: true });

      const analyzeLink = screen.getByText('Analyze').closest('a');
      expect(analyzeLink).toHaveClass('border-transparent');
      expect(analyzeLink).toHaveClass('text-muted-foreground');
      expect(analyzeLink).toHaveClass('hover:text-foreground');
      expect(analyzeLink).toHaveClass('hover:border-border');
    });
  });

  // ============================================
  // Accessibility tests
  // ============================================

  describe('accessibility', () => {
    it('has navigation role', () => {
      renderSiteNav({ siteId: 1 });

      expect(screen.getByRole('navigation')).toBeInTheDocument();
    });

    it('tooltips have tooltip role', async () => {
      renderSiteNav({ siteId: 1, canAnalyze: false });

      const analyzeTab = screen.getByText('Analyze');
      await user.hover(analyzeTab);

      const tooltip = await screen.findByRole('tooltip');
      expect(tooltip).toBeInTheDocument();
    });

    it('enabled tabs are accessible as links', () => {
      renderSiteNav({ siteId: 1, canAnalyze: true, canRecommend: true, canSchedule: true });

      const links = screen.getAllByRole('link');
      expect(links).toHaveLength(7);
    });

    it('disabled tabs are not interactive', () => {
      renderSiteNav({ siteId: 1, canAnalyze: false });

      const analyzeTab = screen.getByText('Analyze').closest('button');
      expect(analyzeTab).toHaveClass('cursor-not-allowed');
      expect(analyzeTab?.tagName).toBe('BUTTON');
    });

    it('tab labels are visible', () => {
      renderSiteNav({ siteId: 1 });

      expect(screen.getByText('Connections')).toBeVisible();
      expect(screen.getByText('Analyze')).toBeVisible();
      expect(screen.getByText('Recommendations')).toBeVisible();
      expect(screen.getByText('Cannibalization')).toBeVisible();
      expect(screen.getByText('Opportunity Map')).toBeVisible();
      expect(screen.getByText('Geographic')).toBeVisible();
      expect(screen.getByText('Device')).toBeVisible();
      expect(screen.getByText('Schedule')).toBeVisible();
    });
  });

  // ============================================
  // Edge cases
  // ============================================

  describe('edge cases', () => {
    it('handles missing optional props gracefully', () => {
      renderSiteNav({ siteId: 1 });

      // Should render without errors, with Analyze and Recommendations disabled
      expect(screen.getByText('Connections').closest('a')).toBeInTheDocument();
      expect(screen.getByText('Analyze').closest('button')).toHaveClass('cursor-not-allowed');
      expect(screen.getByText('Recommendations').closest('button')).toHaveClass(
        'cursor-not-allowed',
      );
    });

    it('handles canAnalyze false explicitly', () => {
      renderSiteNav({ siteId: 1, canAnalyze: false });

      const analyzeTab = screen.getByText('Analyze').closest('button');
      expect(analyzeTab).toHaveClass('cursor-not-allowed');
    });

    it('handles canRecommend false explicitly', () => {
      renderSiteNav({ siteId: 1, canRecommend: false });

      const recommendationsTab = screen.getByText('Recommendations').closest('button');
      expect(recommendationsTab).toHaveClass('cursor-not-allowed');
    });

    it('handles different siteId values', () => {
      renderSiteNav({ siteId: 999, canAnalyze: true });

      const analyzeLink = screen.getByText('Analyze').closest('a');
      expect(analyzeLink).toHaveAttribute('href', '/sites/999/analyze');
    });
  });
});
