import { describe, it, expect, vi } from 'vitest';
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import Scheduler from '../Scheduler';

// Mock the outlet context
const mockOutletContext = vi.fn();
vi.mock('react-router-dom', async () => {
  const actual = await vi.importActual('react-router-dom');
  return {
    ...actual,
    useOutletContext: () => mockOutletContext(),
  };
});

// Mock hooks
vi.mock('../../hooks/useAppointments', () => ({
  useAppointments: vi.fn(() => ({ data: [], isLoading: false })),
  useUpdateAppointment: vi.fn(),
  useDeleteAppointment: vi.fn(),
}));

vi.mock('../../hooks/useResources', () => ({
  useResources: vi.fn(() => ({ data: [], isLoading: false })),
}));

vi.mock('../../hooks/useServices', () => ({
  useServices: vi.fn(() => ({ data: [], isLoading: false })),
}));

// Mock child components
vi.mock('../ResourceScheduler', () => ({
  default: () => <div data-testid="resource-scheduler">Resource Scheduler</div>,
}));

vi.mock('../OwnerScheduler', () => ({
  default: () => <div data-testid="owner-scheduler">Owner Scheduler</div>,
}));

import { useAppointments } from '../../hooks/useAppointments';
import { useResources } from '../../hooks/useResources';
import { useServices } from '../../hooks/useServices';

const mockUseAppointments = useAppointments as ReturnType<typeof vi.fn>;
const mockUseResources = useResources as ReturnType<typeof vi.fn>;
const mockUseServices = useServices as ReturnType<typeof vi.fn>;

describe('Scheduler', () => {
  const defaultContext = {
    user: { id: '1', role: 'owner', email: 'test@test.com' },
    business: { id: '1', name: 'Test Business' },
  };

  beforeEach(() => {
    vi.clearAllMocks();
    mockOutletContext.mockReturnValue(defaultContext);
    mockUseAppointments.mockReturnValue({ data: [], isLoading: false });
    mockUseResources.mockReturnValue({ data: [], isLoading: false });
    mockUseServices.mockReturnValue({ data: [], isLoading: false });
  });

  it('renders loading state when appointments are loading', () => {
    mockUseAppointments.mockReturnValue({ data: [], isLoading: true });

    render(
      <MemoryRouter>
        <Scheduler />
      </MemoryRouter>
    );

    expect(screen.getByText('Loading scheduler...')).toBeInTheDocument();
  });

  it('renders loading state when resources are loading', () => {
    mockUseResources.mockReturnValue({ data: [], isLoading: true });

    render(
      <MemoryRouter>
        <Scheduler />
      </MemoryRouter>
    );

    expect(screen.getByText('Loading scheduler...')).toBeInTheDocument();
  });

  it('renders loading state when services are loading', () => {
    mockUseServices.mockReturnValue({ data: [], isLoading: true });

    render(
      <MemoryRouter>
        <Scheduler />
      </MemoryRouter>
    );

    expect(screen.getByText('Loading scheduler...')).toBeInTheDocument();
  });

  it('renders ResourceScheduler for resource role', () => {
    mockOutletContext.mockReturnValue({
      ...defaultContext,
      user: { ...defaultContext.user, role: 'resource' },
    });

    render(
      <MemoryRouter>
        <Scheduler />
      </MemoryRouter>
    );

    expect(screen.getByTestId('resource-scheduler')).toBeInTheDocument();
  });

  it('renders OwnerScheduler for owner role', () => {
    mockOutletContext.mockReturnValue({
      ...defaultContext,
      user: { ...defaultContext.user, role: 'owner' },
    });

    render(
      <MemoryRouter>
        <Scheduler />
      </MemoryRouter>
    );

    expect(screen.getByTestId('owner-scheduler')).toBeInTheDocument();
  });

  it('renders OwnerScheduler for manager role', () => {
    mockOutletContext.mockReturnValue({
      ...defaultContext,
      user: { ...defaultContext.user, role: 'manager' },
    });

    render(
      <MemoryRouter>
        <Scheduler />
      </MemoryRouter>
    );

    expect(screen.getByTestId('owner-scheduler')).toBeInTheDocument();
  });

  it('renders OwnerScheduler for staff role', () => {
    mockOutletContext.mockReturnValue({
      ...defaultContext,
      user: { ...defaultContext.user, role: 'staff' },
    });

    render(
      <MemoryRouter>
        <Scheduler />
      </MemoryRouter>
    );

    expect(screen.getByTestId('owner-scheduler')).toBeInTheDocument();
  });
});
