import { configureStore } from '@reduxjs/toolkit';
import SubscriptionSlice, { fetchUserSubscriptions, fetchAllPlans, fetchPlan, subscribeToPlan, confirmSubscriptionPayment } from '../SubscriptionSlice';

jest.mock('@/services/api/api', () => ({
  apiGet: jest.fn(),
  apiPost: jest.fn(),
  apiPut: jest.fn(),
  apiDelete: jest.fn(),
}));

jest.mock('antd', () => ({
  message: { success: jest.fn(), error: jest.fn(), warning: jest.fn() },
}));

jest.mock('@umijs/max', () => ({
  history: { push: jest.fn() },
}));

jest.mock('@/constants', () => ({
  LOCAL_STORAGE: { AUTH_USER: 'auth_user' },
  RESPONSE_CODES: {
    SUBSCRIPTION: {
      TRIAL_PLAN_SUBSCRIBED: 'TRIAL_SUBSCRIBED',
      PAID_PLAN_SUBSCRIBED: 'PAID_SUBSCRIBED',
    },
  },
}));

const createStore = () => configureStore({ reducer: { subscription: SubscriptionSlice.reducer } });

describe('SubscriptionSlice', () => {
  it('has correct initial state', () => {
    const store = createStore();
    const state = store.getState().subscription;
    expect(state.loading).toBe(false);
    expect(state.error).toBeNull();
    expect(state.plans).toBeUndefined();
    expect(state.plan).toBeUndefined();
    expect(state.subscribing).toBe(false);
    expect(state.confirmingPayment).toBe(false);
    expect(state.paymentConfirmed).toBe(false);
  });

  describe('fetchUserSubscriptions', () => {
    it('sets loading on pending', () => {
      const store = createStore();
      store.dispatch({ type: fetchUserSubscriptions.pending.type });
      expect(store.getState().subscription.loading).toBe(true);
    });

    it('sets userSubscription on fulfilled', () => {
      const store = createStore();
      const sub = { id: 's1', plan: 'pro' };
      store.dispatch({ type: fetchUserSubscriptions.fulfilled.type, payload: sub });
      expect(store.getState().subscription.userSubscription).toEqual(sub);
      expect(store.getState().subscription.loading).toBe(false);
    });
  });

  describe('fetchAllPlans', () => {
    it('populates plans on fulfilled', () => {
      const store = createStore();
      const plans = [{ id: 'p1', name: 'Basic' }];
      store.dispatch({ type: fetchAllPlans.fulfilled.type, payload: plans });
      expect(store.getState().subscription.plans).toEqual(plans);
    });
  });

  describe('fetchPlan', () => {
    it('sets plan on fulfilled', () => {
      const store = createStore();
      const plan = { id: 'p1', name: 'Pro' };
      store.dispatch({ type: fetchPlan.fulfilled.type, payload: plan });
      expect(store.getState().subscription.plan).toEqual(plan);
    });

    it('sets loadingPlan on pending', () => {
      const store = createStore();
      store.dispatch({ type: fetchPlan.pending.type });
      expect(store.getState().subscription.loadingPlan).toBe(true);
    });
  });

  describe('confirmSubscriptionPayment', () => {
    it('sets confirmingPayment on pending', () => {
      const store = createStore();
      store.dispatch({ type: confirmSubscriptionPayment.pending.type });
      expect(store.getState().subscription.confirmingPayment).toBe(true);
    });

    it('sets paymentConfirmed on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: confirmSubscriptionPayment.fulfilled.type, payload: true });
      expect(store.getState().subscription.paymentConfirmed).toBe(true);
      expect(store.getState().subscription.confirmingPayment).toBe(false);
    });
  });
});
