import { renderHook, act } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { CartProvider, useCart } from './CartContext';
import { ReactNode } from 'react';
import { Product, ProductLicense } from '@/types';
import { ToastProvider } from './ToastContext';

// Mock useToast via ToastProvider
const mockAddToast = vi.fn();

vi.mock('./ToastContext', async () => {
  const actual = await vi.importActual('./ToastContext');
  return {
    ...actual,
    ToastProvider: ({ children }: { children: ReactNode }) => children,
    useToast: () => ({
      addToast: mockAddToast,
    }),
  };
});

const mockProduct: Product = {
  id: '1',
  title: 'Test Product',
  price: 9.99,
  currency: 'USD',
  type: 'track',
};

const wrapper = ({ children }: { children: ReactNode }) => (
  <CartProvider>{children}</CartProvider>
);

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

  it('should provide cart context', () => {
    const { result } = renderHook(() => useCart(), { wrapper });

    expect(result.current).toBeDefined();
    expect(result.current).toHaveProperty('cart');
    expect(result.current).toHaveProperty('addToCart');
    expect(result.current).toHaveProperty('removeFromCart');
    expect(result.current).toHaveProperty('clearCart');
  });

  it('should have empty cart initially', () => {
    const { result } = renderHook(() => useCart(), { wrapper });

    expect(result.current.cart).toEqual([]);
  });

  it('should add product to cart', () => {
    const { result } = renderHook(() => useCart(), { wrapper });

    act(() => {
      result.current.addToCart(mockProduct);
    });

    expect(result.current.cart).toHaveLength(1);
    expect(result.current.cart[0].id).toBe(mockProduct.id);
    expect(result.current.cart[0].title).toBe(mockProduct.title);
  });

  it('should remove product from cart', () => {
    const { result } = renderHook(() => useCart(), { wrapper });

    act(() => {
      result.current.addToCart(mockProduct);
    });

    expect(result.current.cart).toHaveLength(1);

    const cartId = result.current.cart[0].cartId;

    act(() => {
      result.current.removeFromCart(cartId);
    });

    expect(result.current.cart).toHaveLength(0);
  });

  it('should clear cart', () => {
    const { result } = renderHook(() => useCart(), { wrapper });

    act(() => {
      result.current.addToCart(mockProduct);
      result.current.addToCart({ ...mockProduct, id: '2' });
    });

    expect(result.current.cart).toHaveLength(2);

    act(() => {
      result.current.clearCart();
    });

    expect(result.current.cart).toHaveLength(0);
  });

  it('should add product with license', () => {
    const { result } = renderHook(() => useCart(), { wrapper });

    const license: ProductLicense = {
      id: 'std',
      name: 'Standard',
      price: 9.99,
      features: ['Royalty Free'],
    };

    act(() => {
      result.current.addToCart(mockProduct, license);
    });

    expect(result.current.cart).toHaveLength(1);
    expect(result.current.cart[0].selectedLicense).toEqual(license);
  });
});
