import React from 'react';
import { render, fireEvent, waitFor } from '@testing-library/react-native';
import { api } from '@/services/api';

// Mock dependencies
jest.mock('@/services/api');
jest.mock('expo-router', () => ({
  useLocalSearchParams: () => ({ id: '1' }),
  router: { back: jest.fn(), replace: jest.fn() },
}));
jest.mock('@/contexts/AuthContext', () => ({
  useAuth: () => ({
    user: { id: '1', email: 'test@example.com' },
  }),
}));
jest.mock('@stripe/stripe-react-native', () => ({
  usePaymentSheet: () => ({
    initPaymentSheet: jest.fn(),
    presentPaymentSheet: jest.fn(),
  }),
}));

// Import the screen after mocks are set up
import SubscriptionScreen from '@/app/(tabs)/beneficiaries/[id]/subscription';

describe('SubscriptionScreen - Error Handling', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('displays error message when beneficiary loading fails', async () => {
    const mockError = { ok: false, error: { message: 'Failed to load beneficiary data' } };
    (api.getWellNuoBeneficiary as jest.Mock).mockResolvedValue(mockError);
    (api.getTransactionHistory as jest.Mock).mockResolvedValue({ ok: true, data: { transactions: [] } });

    const { findByText } = render(<SubscriptionScreen />);

    await waitFor(() => {
      expect(findByText('Failed to load beneficiary data')).toBeTruthy();
    });
  });

  it('displays retry button when error occurs', async () => {
    const mockError = { ok: false, error: { message: 'Network error' } };
    (api.getWellNuoBeneficiary as jest.Mock).mockResolvedValue(mockError);
    (api.getTransactionHistory as jest.Mock).mockResolvedValue({ ok: true, data: { transactions: [] } });

    const { findByText } = render(<SubscriptionScreen />);

    await waitFor(() => {
      expect(findByText('Try Again')).toBeTruthy();
    });
  });

  it('retries loading beneficiary when retry button is pressed', async () => {
    const mockError = { ok: false, error: { message: 'Network error' } };
    const mockSuccess = {
      ok: true,
      data: {
        id: 1,
        name: 'Test User',
        subscription: { status: 'active' },
      },
    };

    (api.getWellNuoBeneficiary as jest.Mock)
      .mockResolvedValueOnce(mockError)
      .mockResolvedValueOnce(mockSuccess);
    (api.getTransactionHistory as jest.Mock).mockResolvedValue({ ok: true, data: { transactions: [] } });

    const { findByText, queryByText } = render(<SubscriptionScreen />);

    // Wait for error to appear
    await waitFor(() => {
      expect(findByText('Try Again')).toBeTruthy();
    });

    // Press retry button
    const retryButton = await findByText('Try Again');
    fireEvent.press(retryButton);

    // Wait for error to disappear after successful retry
    await waitFor(() => {
      expect(queryByText('Network error')).toBeNull();
    });

    // Verify API was called twice (initial + retry)
    expect(api.getWellNuoBeneficiary).toHaveBeenCalledTimes(2);
  });

  it('displays generic error message for exceptions', async () => {
    (api.getWellNuoBeneficiary as jest.Mock).mockRejectedValue(
      new Error('Connection timeout')
    );
    (api.getTransactionHistory as jest.Mock).mockResolvedValue({ ok: true, data: { transactions: [] } });

    const { findByText } = render(<SubscriptionScreen />);

    await waitFor(() => {
      expect(findByText(/Connection timeout|Failed to load beneficiary data/)).toBeTruthy();
    });
  });
});
