import React from 'react';
import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { ServiceProvider, useServices } from './ServiceContext';
import { CartService } from '../domains/cart/services/CartService';
import { NotificationService } from '../domains/notification/services/NotificationService';
import { OrderService } from '../domains/order/services/OrderService';
import { PaymentService } from '../domains/payment/services/PaymentService';
import { ProductService } from '../domains/product/services/ProductService';
import { UserService } from '../domains/user/services/UserService';

// Mock services
const mockServices = {
  cartService: {} as CartService,
  notificationService: {} as NotificationService,
  orderService: {} as OrderService,
  paymentService: {} as PaymentService,
  productService: {} as ProductService,
  userService: {} as UserService,
};

// Test component to access services
const TestComponent: React.FC = () => {
  const services = useServices();
  return (
    <div>
      <div data-testid="services-count">{Object.keys(services).length}</div>
      {Object.keys(services).map(key => (
        <div key={key} data-testid={`service-${key}`}>
          {key}
        </div>
      ))}
    </div>
  );
};

describe('ServiceContext', () => {
  it('should provide default services', () => {
    render(
      <ServiceProvider>
        <TestComponent />
      </ServiceProvider>
    );

    expect(screen.getByTestId('services-count')).toHaveTextContent('6');
    expect(screen.getByTestId('service-cartService')).toBeInTheDocument();
    expect(screen.getByTestId('service-notificationService')).toBeInTheDocument();
    expect(screen.getByTestId('service-orderService')).toBeInTheDocument();
    expect(screen.getByTestId('service-paymentService')).toBeInTheDocument();
    expect(screen.getByTestId('service-productService')).toBeInTheDocument();
    expect(screen.getByTestId('service-userService')).toBeInTheDocument();
  });

  it('should allow service override', () => {
    render(
      <ServiceProvider services={mockServices}>
        <TestComponent />
      </ServiceProvider>
    );

    expect(screen.getByTestId('services-count')).toHaveTextContent('6');
  });

  it('should provide services through useServices hook', () => {
    let capturedServices: any;
    
    const TestHook: React.FC = () => {
      capturedServices = useServices();
      return null;
    };

    render(
      <ServiceProvider>
        <TestHook />
      </ServiceProvider>
    );

    expect(capturedServices).toBeDefined();
    expect(Object.keys(capturedServices)).toHaveLength(6);
    expect(capturedServices.cartService).toBeDefined();
    expect(capturedServices.notificationService).toBeDefined();
    expect(capturedServices.orderService).toBeDefined();
    expect(capturedServices.paymentService).toBeDefined();
    expect(capturedServices.productService).toBeDefined();
    expect(capturedServices.userService).toBeDefined();
  });
});
