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

const { mockTrackProductEvent } = vi.hoisted(() => ({ mockTrackProductEvent: vi.fn() }));
vi.mock('@/lib/analytics', () => ({ trackProductEvent: mockTrackProductEvent }));

import CalendarIndex from './Index';

vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    usePage: vi.fn(() => ({
      props: {
        auth: {
          user: {
            name: 'Test User',
            email: 'test@example.com',
          },
        },
        features: {
          billing: false,
          notifications: false,
        },
        sites: [],
        limits: null,
        ai_defaults: { model: 'gpt-4o-mini', temperature: 0.7 },
        polling_interval_ms: 5000,
      },
    })),
    Head: ({ title }: { title: string }) => <title>{title}</title>,
    Link: ({ children, href }: { children: React.ReactNode; href: string }) => (
      <a href={href}>{children}</a>
    ),
    router: {
      get: vi.fn(),
      on: vi.fn(() => vi.fn()),
    },
  };
});

vi.mock('@/Components/theme/use-theme', () => ({
  useTheme: vi.fn(() => ({
    theme: 'system',
    setTheme: vi.fn(),
    resolvedTheme: 'light',
  })),
}));

vi.mock('@/Components/Navigation/SiteNav', () => ({
  default: () => <div data-testid="site-nav" />,
}));

vi.mock('@/Components/Calendar/CalendarView', () => ({
  default: ({ entries }: { entries: unknown[] }) => (
    <div data-testid="calendar-view">Calendar View: {entries.length} entries</div>
  ),
}));

vi.mock('@/Components/Calendar/EventCard', () => ({
  default: ({ entry }: { entry: { id: number; title: string } }) => (
    <div data-testid={`event-card-${entry.id}`}>{entry.title}</div>
  ),
}));

vi.mock('@/Components/Shared/InertiaPagination', () => ({
  default: () => <div data-testid="pagination">Pagination</div>,
}));

vi.mock('@/Components/ui/empty-state', () => ({
  EmptyState: ({ title, description }: { title: string; description?: string }) => (
    <div data-testid="empty-state">
      {title}: {description}
    </div>
  ),
}));

const defaultProps = {
  site: { id: 1, name: 'Test Site', domain: 'https://test.com' },
  entries: {
    data: [
      {
        id: 1,
        title: 'Refresh content on Homepage',
        description: 'Update stale content based on freshness analysis',
        due_date: '2026-03-01',
        scheduled_date: null,
        status: 'planned' as const,
        source_type: 'App\\Models\\FreshnessRecommendation',
        source_id: 10,
        page_url: 'https://test.com/',
        metadata: null,
      },
      {
        id: 2,
        title: 'Write blog post on SEO trends',
        description: 'Cover topic gap opportunity',
        due_date: '2026-03-05',
        scheduled_date: null,
        status: 'in_progress' as const,
        source_type: 'App\\Models\\TopicGapSuggestion',
        source_id: 5,
        page_url: null,
        metadata: { keywords: ['seo', 'trends', '2026'] },
      },
      {
        id: 3,
        title: 'Update meta tags',
        description: null,
        due_date: '2026-02-15',
        scheduled_date: null,
        status: 'overdue' as const,
        source_type: null,
        source_id: null,
        page_url: 'https://test.com/about',
        metadata: null,
      },
    ],
    links: [
      { url: null, label: '&laquo; Previous', active: false },
      { url: '/calendar?page=1', label: '1', active: true },
      { url: null, label: 'Next &raquo;', active: false },
    ],
    current_page: 1,
    last_page: 1,
  },
  filters: {
    status: null,
    source_type: null,
    start_date: null,
    end_date: null,
    sort_by: null,
  },
  counts: {
    total: 10,
    planned: 3,
    in_progress: 2,
    completed: 4,
    overdue: 1,
  },
};

describe('CalendarIndex', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  describe('analytics', () => {
    it('fires calendar_viewed with site_id on mount', () => {
      render(<CalendarIndex {...defaultProps} />);
      expect(mockTrackProductEvent).toHaveBeenCalledWith('calendar_viewed', { site_id: '1' });
    });

    it('fires feature_used with seo_calendar on mount', () => {
      render(<CalendarIndex {...defaultProps} />);
      expect(mockTrackProductEvent).toHaveBeenCalledWith('feature_used', {
        feature: 'seo_calendar',
      });
    });
  });

  describe('rendering', () => {
    it('renders the page title', () => {
      render(<CalendarIndex {...defaultProps} />);
      const title = screen.getByRole('heading', { name: /SEO Calendar/i });
      expect(title).toBeInTheDocument();
    });

    it('renders site navigation', () => {
      render(<CalendarIndex {...defaultProps} />);
      expect(screen.getByTestId('site-nav')).toBeInTheDocument();
    });

    it('renders stats cards with counts', () => {
      render(<CalendarIndex {...defaultProps} />);
      expect(screen.getByText('Total Tasks')).toBeInTheDocument();
      expect(screen.getByText('10')).toBeInTheDocument();
      expect(screen.getByText('Planned')).toBeInTheDocument();
      expect(screen.getByText('3')).toBeInTheDocument();
      expect(screen.getByText('In Progress')).toBeInTheDocument();
      expect(screen.getByText('2')).toBeInTheDocument();
      expect(screen.getByText('Completed')).toBeInTheDocument();
      expect(screen.getByText('4')).toBeInTheDocument();
      expect(screen.getByText('Overdue')).toBeInTheDocument();
      expect(screen.getByText('1')).toBeInTheDocument();
    });

    it('renders create task button', () => {
      render(<CalendarIndex {...defaultProps} />);
      const createButton = screen.getByText('Create Task');
      expect(createButton).toBeInTheDocument();
    });

    it('renders filter controls', () => {
      render(<CalendarIndex {...defaultProps} />);
      expect(screen.getAllByText('Filters').length).toBeGreaterThan(0);
    });
  });

  describe('view modes', () => {
    it('renders calendar view by default', () => {
      render(<CalendarIndex {...defaultProps} />);
      expect(screen.getByTestId('calendar-view')).toBeInTheDocument();
      expect(screen.getByText(/Calendar View: 3 entries/)).toBeInTheDocument();
    });

    it('switches to list view when list tab is clicked', async () => {
      const user = userEvent.setup();
      render(<CalendarIndex {...defaultProps} />);

      const listViewButton = screen.getByRole('tab', { name: /List View/i });
      await user.click(listViewButton);

      // Event cards should be visible
      expect(screen.getByTestId('event-card-1')).toBeInTheDocument();
      expect(screen.getByTestId('event-card-2')).toBeInTheDocument();
      expect(screen.getByTestId('event-card-3')).toBeInTheDocument();
    });

    it('displays pagination in list view', async () => {
      const user = userEvent.setup();
      render(<CalendarIndex {...defaultProps} />);

      const listViewButton = screen.getByRole('tab', { name: /List View/i });
      await user.click(listViewButton);

      expect(screen.getByTestId('pagination')).toBeInTheDocument();
    });
  });

  describe('empty state', () => {
    it('shows empty state when no entries in calendar view', () => {
      const emptyProps = {
        ...defaultProps,
        entries: {
          ...defaultProps.entries,
          data: [],
        },
        counts: {
          total: 0,
          planned: 0,
          in_progress: 0,
          completed: 0,
          overdue: 0,
        },
      };

      render(<CalendarIndex {...emptyProps} />);
      expect(screen.getByTestId('empty-state')).toBeInTheDocument();
      expect(screen.getByText(/No calendar tasks/i)).toBeInTheDocument();
    });

    it('shows empty state when no entries in list view', async () => {
      const user = userEvent.setup();
      const emptyProps = {
        ...defaultProps,
        entries: {
          ...defaultProps.entries,
          data: [],
        },
        counts: {
          total: 0,
          planned: 0,
          in_progress: 0,
          completed: 0,
          overdue: 0,
        },
      };

      render(<CalendarIndex {...emptyProps} />);

      const listViewButton = screen.getByRole('tab', { name: /List View/i });
      await user.click(listViewButton);

      expect(screen.getByTestId('empty-state')).toBeInTheDocument();
    });
  });

  describe('filtering', () => {
    it('displays active filter chips when filters are applied', () => {
      const filteredProps = {
        ...defaultProps,
        filters: {
          ...defaultProps.filters,
          status: 'planned',
          source_type: 'App\\Models\\FreshnessRecommendation',
        },
      };

      render(<CalendarIndex {...filteredProps} />);
      expect(screen.getByText('Active Filters:')).toBeInTheDocument();
      expect(screen.getByText(/Status: Planned/)).toBeInTheDocument();
      expect(screen.getByText(/Source: Freshness/)).toBeInTheDocument();
    });

    it('displays date range filter chip when date filters are applied', () => {
      const filteredProps = {
        ...defaultProps,
        filters: {
          ...defaultProps.filters,
          start_date: '2026-03-01',
          end_date: '2026-03-31',
        },
      };

      render(<CalendarIndex {...filteredProps} />);
      expect(screen.getByText(/Dates: 2026-03-01 to 2026-03-31/)).toBeInTheDocument();
    });

    it('displays clear all button when filters are active', () => {
      const filteredProps = {
        ...defaultProps,
        filters: {
          ...defaultProps.filters,
          status: 'planned',
        },
      };

      render(<CalendarIndex {...filteredProps} />);
      expect(screen.getByText('Clear All')).toBeInTheDocument();
    });

    it('does not show active filters section when no filters applied', () => {
      render(<CalendarIndex {...defaultProps} />);
      expect(screen.queryByText('Active Filters:')).not.toBeInTheDocument();
    });
  });

  describe('filter controls', () => {
    it('renders status filter select', () => {
      render(<CalendarIndex {...defaultProps} />);
      expect(screen.getByLabelText('Status')).toBeInTheDocument();
    });

    it('renders source type filter select', () => {
      render(<CalendarIndex {...defaultProps} />);
      expect(screen.getByLabelText('Source Type')).toBeInTheDocument();
    });

    it('renders start date input', () => {
      render(<CalendarIndex {...defaultProps} />);
      expect(screen.getByLabelText('Start Date')).toBeInTheDocument();
    });

    it('renders end date input', () => {
      render(<CalendarIndex {...defaultProps} />);
      expect(screen.getByLabelText('End Date')).toBeInTheDocument();
    });
  });

  describe('stats highlighting', () => {
    it('highlights overdue count when there are overdue tasks', () => {
      const propsWithOverdue = {
        ...defaultProps,
        counts: {
          ...defaultProps.counts,
          overdue: 5,
        },
      };

      render(<CalendarIndex {...propsWithOverdue} />);
      // The overdue card should have special styling
      expect(screen.getByText('Overdue')).toBeInTheDocument();
      expect(screen.getByText('5')).toBeInTheDocument();
    });

    it('does not highlight overdue count when there are no overdue tasks', () => {
      const propsWithNoOverdue = {
        ...defaultProps,
        counts: {
          ...defaultProps.counts,
          overdue: 0,
        },
      };

      render(<CalendarIndex {...propsWithNoOverdue} />);
      // Should still render but without special highlighting
      expect(screen.getByText('Overdue')).toBeInTheDocument();
    });
  });

  describe('mobile filters', () => {
    it('renders mobile filter button', () => {
      render(<CalendarIndex {...defaultProps} />);
      // The filter button should be in the document (even if hidden on desktop)
      const filterButtons = screen.getAllByText('Filters');
      expect(filterButtons.length).toBeGreaterThan(0);
    });
  });

  describe('entries display', () => {
    it('displays all entries in list view', async () => {
      const user = userEvent.setup();
      render(<CalendarIndex {...defaultProps} />);

      const listViewButton = screen.getByRole('tab', { name: /List View/i });
      await user.click(listViewButton);

      expect(screen.getByText('Refresh content on Homepage')).toBeInTheDocument();
      expect(screen.getByText('Write blog post on SEO trends')).toBeInTheDocument();
      expect(screen.getByText('Update meta tags')).toBeInTheDocument();
    });
  });

  describe('accessibility', () => {
    it('has proper heading structure', () => {
      render(<CalendarIndex {...defaultProps} />);
      const heading = screen.getByRole('heading', { name: /SEO Calendar/i });
      expect(heading).toBeInTheDocument();
    });

    it('has accessible tab navigation', () => {
      render(<CalendarIndex {...defaultProps} />);
      const calendarTab = screen.getByRole('tab', { name: /Calendar View/i });
      const listTab = screen.getByRole('tab', { name: /List View/i });
      expect(calendarTab).toBeInTheDocument();
      expect(listTab).toBeInTheDocument();
    });
  });
});
