import { describe, it, expect, beforeEach, vi } from 'vitest';
import { setActivePinia, createPinia } from 'pinia';
import { useCartStore } from '@/stores/CartStore.js';
import * as ftch from '@/utils/ftch.js';

// Мокаем API функции
vi.mock('@/utils/ftch.js', () => ({
  getCart: vi.fn(),
  addToCart: vi.fn(),
  cartRemoveItem: vi.fn(),
  cartEditItem: vi.fn(),
  setCoupon: vi.fn(),
  setVoucher: vi.fn(),
}));

// Мокаем другие stores
vi.mock('@/stores/yaMetrikaStore.js', () => ({
  useYaMetrikaStore: () => ({
    dataLayerPush: vi.fn(),
  }),
}));

vi.mock('@/stores/SettingsStore.js', () => ({
  useSettingsStore: () => ({
    currency_code: 'RUB',
  }),
}));

describe('CartStore', () => {
  beforeEach(() => {
    setActivePinia(createPinia());
    vi.clearAllMocks();
  });

  describe('state', () => {
    it('должен инициализироваться с пустыми значениями', () => {
      const store = useCartStore();
      
      expect(store.items).toEqual([]);
      expect(store.productsCount).toBe(0);
      expect(store.total).toBe(0);
      expect(store.isLoading).toBe(false);
      expect(store.coupon).toBe('');
      expect(store.voucher).toBe('');
    });
  });

  describe('getters', () => {
    it('canCheckout должен возвращать false при загрузке', () => {
      const store = useCartStore();
      store.isLoading = true;
      
      expect(store.canCheckout).toBe(false);
    });

    it('canCheckout должен возвращать false при наличии ошибки', () => {
      const store = useCartStore();
      store.error_warning = 'Ошибка';
      
      expect(store.canCheckout).toBe(false);
    });
  });

  describe('actions', () => {
    describe('getProducts', () => {
      it('должен загружать продукты из API', async () => {
        const mockData = {
          data: {
            products: [{ id: 1, name: 'Product 1' }],
            total_products_count: 1,
            totals: { total: 1000 },
            error_warning: '',
            attention: '',
            success: '',
          },
        };

        ftch.getCart.mockResolvedValue(mockData);

        const store = useCartStore();
        await store.getProducts();

        expect(store.items).toEqual(mockData.data.products);
        expect(store.productsCount).toBe(1);
        expect(store.isLoading).toBe(false);
      });

      it('должен обрабатывать ошибки', async () => {
        const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
        ftch.getCart.mockRejectedValue(new Error('Network error'));

        const store = useCartStore();
        await store.getProducts();

        expect(store.isLoading).toBe(false);
        expect(consoleErrorSpy).toHaveBeenCalled();
        
        consoleErrorSpy.mockRestore();
      });
    });

    describe('addProduct', () => {
      it('должен добавлять продукт в корзину', async () => {
        const mockResponse = { error: null };
        ftch.addToCart.mockResolvedValue(mockResponse);
        ftch.getCart.mockResolvedValue({
          data: {
            products: [{ id: 1, name: 'Product 1' }],
            total_products_count: 1,
            totals: {},
            error_warning: '',
            attention: '',
            success: '',
          },
        });

        const store = useCartStore();
        await store.addProduct(1, 'Product 1', 100, 2, []);

        expect(ftch.addToCart).toHaveBeenCalled();
        expect(store.isLoading).toBe(false);
      });

      it('должен обрабатывать опции продукта', async () => {
        const mockResponse = { error: null };
        ftch.addToCart.mockResolvedValue(mockResponse);
        ftch.getCart.mockResolvedValue({
          data: {
            products: [],
            total_products_count: 0,
            totals: {},
            error_warning: '',
            attention: '',
            success: '',
          },
        });

        const options = [
          { type: 'checkbox', product_option_id: 1, value: [{ product_option_value_id: 10 }] },
          { type: 'radio', product_option_id: 2, value: { product_option_value_id: 20 } },
          { type: 'text', product_option_id: 3, value: 'test text' },
        ];

        const store = useCartStore();
        await store.addProduct(1, 'Product', 100, 1, options);

        expect(ftch.addToCart).toHaveBeenCalled();
      });

      it('должен выбрасывать ошибку при ошибке API', async () => {
        const mockResponse = { error: 'Product not found' };
        ftch.addToCart.mockResolvedValue(mockResponse);

        const store = useCartStore();
        
        await expect(store.addProduct(1, 'Product', 100)).rejects.toThrow();
      });
    });

    describe('removeItem', () => {
      it('должен удалять товар из корзины', async () => {
        ftch.cartRemoveItem.mockResolvedValue({});
        ftch.getCart.mockResolvedValue({
          data: {
            products: [],
            total_products_count: 0,
            totals: {},
            error_warning: '',
            attention: '',
            success: '',
          },
        });

        const store = useCartStore();
        const cartItem = { product_id: 1, name: 'Product', quantity: 1 };
        
        await store.removeItem(cartItem, 'row123', 0);

        expect(ftch.cartRemoveItem).toHaveBeenCalled();
        expect(store.isLoading).toBe(false);
      });
    });

    describe('setQuantity', () => {
      it('должен изменять количество товара', async () => {
        ftch.cartEditItem.mockResolvedValue({});
        ftch.getCart.mockResolvedValue({
          data: {
            products: [],
            total_products_count: 0,
            totals: {},
            error_warning: '',
            attention: '',
            success: '',
          },
        });

        const store = useCartStore();
        await store.setQuantity('cart123', 5);

        expect(ftch.cartEditItem).toHaveBeenCalled();
        expect(store.isLoading).toBe(false);
      });
    });

    describe('applyCoupon', () => {
      it('должен применять купон успешно', async () => {
        ftch.setCoupon.mockResolvedValue({ error: null });
        ftch.getCart.mockResolvedValue({
          data: {
            products: [],
            total_products_count: 0,
            totals: {},
            error_warning: '',
            attention: '',
            success: '',
          },
        });

        const store = useCartStore();
        store.coupon = 'DISCOUNT10';
        
        await store.applyCoupon();

        expect(ftch.setCoupon).toHaveBeenCalledWith('DISCOUNT10');
        expect(store.error_warning).toBe('');
      });

      it('должен обрабатывать ошибку при применении купона', async () => {
        ftch.setCoupon.mockResolvedValue({ error: 'Invalid coupon' });

        const store = useCartStore();
        store.coupon = 'INVALID';
        
        await store.applyCoupon();

        expect(store.error_coupon).toBe('Invalid coupon');
      });
    });

    describe('applyVoucher', () => {
      it('должен применять ваучер успешно', async () => {
        ftch.setVoucher.mockResolvedValue({ error: null });
        ftch.getCart.mockResolvedValue({
          data: {
            products: [],
            total_products_count: 0,
            totals: {},
            error_warning: '',
            attention: '',
            success: '',
          },
        });

        const store = useCartStore();
        store.voucher = 'VOUCHER123';
        
        await store.applyVoucher();

        expect(ftch.setVoucher).toHaveBeenCalledWith('VOUCHER123');
        expect(store.error_warning).toBe('');
      });
    });
  });
});

