import { describe, it, expect, beforeEach } from 'vitest';
import { useCartStore } from './cartStore';
import type { Product } from '@/types/marketplace';

const mockProduct1: Product = {
  id: 'product-1',
  name: 'Test Product 1',
  description: 'Test Description 1',
  price: 10.99,
  status: 'active',
  seller_id: 'seller-1',
  created_at: '2024-01-01T00:00:00Z',
};

const mockProduct2: Product = {
  id: 'product-2',
  name: 'Test Product 2',
  description: 'Test Description 2',
  price: 19.99,
  status: 'active',
  seller_id: 'seller-2',
  created_at: '2024-01-01T00:00:00Z',
};

describe('CartStore', () => {
  beforeEach(() => {
    // Reset cart state
    useCartStore.getState().clearCart();
  });

  describe('Initial State', () => {
    it('should have empty cart initially', () => {
      const state = useCartStore.getState();
      expect(state.items).toEqual([]);
      expect(state.getItemCount()).toBe(0);
      expect(state.getTotal()).toBe(0);
    });
  });

  describe('addItem', () => {
    it('should add a new product to cart', () => {
      useCartStore.getState().addItem(mockProduct1);

      const state = useCartStore.getState();
      expect(state.items).toHaveLength(1);
      expect(state.items[0].product).toEqual(mockProduct1);
      expect(state.items[0].quantity).toBe(1);
      expect(state.getItemCount()).toBe(1);
    });

    it('should increment quantity when adding same product', () => {
      useCartStore.getState().addItem(mockProduct1);
      useCartStore.getState().addItem(mockProduct1);

      const state = useCartStore.getState();
      expect(state.items).toHaveLength(1);
      expect(state.items[0].quantity).toBe(2);
      expect(state.getItemCount()).toBe(2);
    });

    it('should add multiple different products', () => {
      useCartStore.getState().addItem(mockProduct1);
      useCartStore.getState().addItem(mockProduct2);

      const state = useCartStore.getState();
      expect(state.items).toHaveLength(2);
      expect(state.items[0].product).toEqual(mockProduct1);
      expect(state.items[1].product).toEqual(mockProduct2);
      expect(state.getItemCount()).toBe(2);
    });
  });

  describe('removeItem', () => {
    it('should remove a product from cart', () => {
      useCartStore.getState().addItem(mockProduct1);
      useCartStore.getState().addItem(mockProduct2);

      useCartStore.getState().removeItem('product-1');

      const state = useCartStore.getState();
      expect(state.items).toHaveLength(1);
      expect(state.items[0].product).toEqual(mockProduct2);
    });

    it('should not remove anything if product not in cart', () => {
      useCartStore.getState().addItem(mockProduct1);

      useCartStore.getState().removeItem('non-existent-product');

      const state = useCartStore.getState();
      expect(state.items).toHaveLength(1);
    });
  });

  describe('updateQuantity', () => {
    it('should update product quantity', () => {
      useCartStore.getState().addItem(mockProduct1);

      useCartStore.getState().updateQuantity('product-1', 5);

      const state = useCartStore.getState();
      expect(state.items[0].quantity).toBe(5);
      expect(state.getItemCount()).toBe(5);
    });

    it('should remove item when quantity is set to 0', () => {
      useCartStore.getState().addItem(mockProduct1);

      useCartStore.getState().updateQuantity('product-1', 0);

      const state = useCartStore.getState();
      expect(state.items).toHaveLength(0);
    });

    it('should remove item when quantity is negative', () => {
      useCartStore.getState().addItem(mockProduct1);

      useCartStore.getState().updateQuantity('product-1', -1);

      const state = useCartStore.getState();
      expect(state.items).toHaveLength(0);
    });
  });

  describe('clearCart', () => {
    it('should clear all items from cart', () => {
      useCartStore.getState().addItem(mockProduct1);
      useCartStore.getState().addItem(mockProduct2);

      useCartStore.getState().clearCart();

      const state = useCartStore.getState();
      expect(state.items).toHaveLength(0);
      expect(state.getItemCount()).toBe(0);
      expect(state.getTotal()).toBe(0);
    });
  });

  describe('getTotal', () => {
    it('should calculate total for single item', () => {
      useCartStore.getState().addItem(mockProduct1);

      expect(useCartStore.getState().getTotal()).toBe(10.99);
    });

    it('should calculate total for multiple items', () => {
      useCartStore.getState().addItem(mockProduct1);
      useCartStore.getState().addItem(mockProduct2);

      expect(useCartStore.getState().getTotal()).toBeCloseTo(30.98, 2);
    });

    it('should calculate total with quantities', () => {
      useCartStore.getState().addItem(mockProduct1);
      useCartStore.getState().addItem(mockProduct1);
      useCartStore.getState().addItem(mockProduct2);

      expect(useCartStore.getState().getTotal()).toBe(41.97);
    });

    it('should return 0 for empty cart', () => {
      expect(useCartStore.getState().getTotal()).toBe(0);
    });
  });

  describe('getItemCount', () => {
    it('should return correct item count', () => {
      useCartStore.getState().addItem(mockProduct1);
      expect(useCartStore.getState().getItemCount()).toBe(1);

      useCartStore.getState().addItem(mockProduct1);
      expect(useCartStore.getState().getItemCount()).toBe(2);

      useCartStore.getState().addItem(mockProduct2);
      expect(useCartStore.getState().getItemCount()).toBe(3);
    });

    it('should return 0 for empty cart', () => {
      expect(useCartStore.getState().getItemCount()).toBe(0);
    });
  });
});
