/**
 * useNavigationFlow Hook - Null Safety Tests
 *
 * Tests for null/undefined handling in navigation hook
 */

import { renderHook, act } from '@testing-library/react-native';
import { useNavigationFlow } from '../useNavigationFlow';
import { ROUTES } from '@/services/NavigationController';
import type { Beneficiary } from '@/types';

// Mock expo-router
const mockPush = jest.fn();
const mockReplace = jest.fn();

jest.mock('expo-router', () => ({
  useRouter: () => ({
    push: mockPush,
    replace: mockReplace,
  }),
}));

describe('useNavigationFlow - Null Safety', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    // Suppress console warnings during tests
    jest.spyOn(console, 'warn').mockImplementation(() => {});
    jest.spyOn(console, 'error').mockImplementation(() => {});
  });

  afterEach(() => {
    jest.restoreAllMocks();
  });

  describe('navigate', () => {
    it('should handle null navigation result', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigate(null as any);
      });

      expect(mockPush).not.toHaveBeenCalled();
      expect(mockReplace).not.toHaveBeenCalled();
      expect(console.warn).toHaveBeenCalledWith(
        '[useNavigationFlow] Invalid navigation result:',
        null
      );
    });

    it('should handle undefined navigation result', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigate(undefined as any);
      });

      expect(mockPush).not.toHaveBeenCalled();
      expect(mockReplace).not.toHaveBeenCalled();
      expect(console.warn).toHaveBeenCalledWith(
        '[useNavigationFlow] Invalid navigation result:',
        undefined
      );
    });

    it('should handle navigation result without path', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigate({ path: '' } as any);
      });

      expect(mockPush).not.toHaveBeenCalled();
      expect(mockReplace).not.toHaveBeenCalled();
    });

    it('should navigate successfully with valid result', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigate({ path: ROUTES.TABS.DASHBOARD });
      });

      expect(mockPush).toHaveBeenCalledWith(ROUTES.TABS.DASHBOARD);
    });

    it('should use replace when specified', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigate({ path: ROUTES.TABS.DASHBOARD }, true);
      });

      expect(mockReplace).toHaveBeenCalledWith(ROUTES.TABS.DASHBOARD);
      expect(mockPush).not.toHaveBeenCalled();
    });
  });

  describe('navigateAfterLogin', () => {
    it('should handle null profile', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigateAfterLogin(null, []);
      });

      expect(mockReplace).toHaveBeenCalledWith(ROUTES.AUTH.ENTER_NAME);
    });

    it('should handle undefined profile', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigateAfterLogin(undefined, []);
      });

      expect(mockReplace).toHaveBeenCalledWith(ROUTES.AUTH.ENTER_NAME);
    });

    it('should handle null beneficiaries', () => {
      const { result } = renderHook(() => useNavigationFlow());
      const profile = {
        id: 1,
        email: 'test@example.com',
        firstName: 'John',
        lastName: 'Doe',
        phone: null,
      };

      act(() => {
        result.current.navigateAfterLogin(profile, null);
      });

      expect(mockReplace).toHaveBeenCalledWith(ROUTES.AUTH.ADD_LOVED_ONE);
    });

    it('should handle undefined beneficiaries', () => {
      const { result } = renderHook(() => useNavigationFlow());
      const profile = {
        id: 1,
        email: 'test@example.com',
        firstName: 'John',
        lastName: 'Doe',
        phone: null,
      };

      act(() => {
        result.current.navigateAfterLogin(profile, undefined);
      });

      expect(mockReplace).toHaveBeenCalledWith(ROUTES.AUTH.ADD_LOVED_ONE);
    });
  });

  describe('navigateAfterAddBeneficiary', () => {
    it('should handle null beneficiaryId', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigateAfterAddBeneficiary(null, false);
      });

      expect(mockPush).toHaveBeenCalledWith(ROUTES.AUTH.ADD_LOVED_ONE);
    });

    it('should handle undefined beneficiaryId', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigateAfterAddBeneficiary(undefined, false);
      });

      expect(mockPush).toHaveBeenCalledWith(ROUTES.AUTH.ADD_LOVED_ONE);
    });

    it('should navigate successfully with valid beneficiaryId', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigateAfterAddBeneficiary(1, false);
      });

      expect(mockPush).toHaveBeenCalledWith({
        pathname: ROUTES.AUTH.PURCHASE,
        params: { beneficiaryId: 1 },
      });
    });
  });

  describe('navigateAfterPurchase', () => {
    it('should handle null beneficiaryId', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigateAfterPurchase(null, {});
      });

      expect(mockPush).toHaveBeenCalledWith(ROUTES.AUTH.ADD_LOVED_ONE);
    });

    it('should handle undefined beneficiaryId', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigateAfterPurchase(undefined, {});
      });

      expect(mockPush).toHaveBeenCalledWith(ROUTES.AUTH.ADD_LOVED_ONE);
    });

    it('should handle null options', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigateAfterPurchase(1, null);
      });

      expect(mockPush).toHaveBeenCalled();
    });

    it('should handle undefined options', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigateAfterPurchase(1, undefined);
      });

      expect(mockPush).toHaveBeenCalled();
    });
  });

  describe('navigateToBeneficiary', () => {
    it('should handle null beneficiary', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigateToBeneficiary(null, 'view');
      });

      expect(mockPush).toHaveBeenCalledWith(ROUTES.TABS.BENEFICIARIES);
    });

    it('should handle undefined beneficiary', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.navigateToBeneficiary(undefined, 'view');
      });

      expect(mockPush).toHaveBeenCalledWith(ROUTES.TABS.BENEFICIARIES);
    });

    it('should navigate successfully with valid beneficiary', () => {
      const { result } = renderHook(() => useNavigationFlow());
      const beneficiary: Beneficiary = {
        id: 1,
        name: 'Mom',
        displayName: 'Mom',
        status: 'online',
      };

      act(() => {
        result.current.navigateToBeneficiary(beneficiary, 'view');
      });

      expect(mockPush).toHaveBeenCalledWith(ROUTES.BENEFICIARY.DETAIL(1));
    });
  });

  describe('goToPurchase', () => {
    it('should handle null beneficiaryId', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.goToPurchase(null);
      });

      expect(mockPush).not.toHaveBeenCalled();
      expect(console.warn).toHaveBeenCalledWith(
        '[useNavigationFlow] Invalid beneficiaryId for purchase:',
        null
      );
    });

    it('should handle undefined beneficiaryId', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.goToPurchase(undefined);
      });

      expect(mockPush).not.toHaveBeenCalled();
      expect(console.warn).toHaveBeenCalledWith(
        '[useNavigationFlow] Invalid beneficiaryId for purchase:',
        undefined
      );
    });

    it('should handle invalid beneficiaryId type', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.goToPurchase('invalid' as any);
      });

      expect(mockPush).not.toHaveBeenCalled();
      expect(console.warn).toHaveBeenCalledWith(
        '[useNavigationFlow] Invalid beneficiaryId for purchase:',
        'invalid'
      );
    });

    it('should navigate successfully with valid beneficiaryId', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.goToPurchase(1);
      });

      expect(mockPush).toHaveBeenCalledWith({
        pathname: ROUTES.AUTH.PURCHASE,
        params: { beneficiaryId: 1 },
      });
    });
  });

  describe('goToActivate', () => {
    it('should handle null beneficiaryId', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.goToActivate(null);
      });

      expect(mockPush).not.toHaveBeenCalled();
      expect(console.warn).toHaveBeenCalledWith(
        '[useNavigationFlow] Invalid beneficiaryId for activation:',
        null
      );
    });

    it('should handle undefined beneficiaryId', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.goToActivate(undefined);
      });

      expect(mockPush).not.toHaveBeenCalled();
      expect(console.warn).toHaveBeenCalledWith(
        '[useNavigationFlow] Invalid beneficiaryId for activation:',
        undefined
      );
    });

    it('should navigate successfully with valid beneficiaryId', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.goToActivate(1);
      });

      expect(mockPush).toHaveBeenCalledWith({
        pathname: ROUTES.AUTH.ACTIVATE,
        params: { beneficiaryId: 1 },
      });
    });

    it('should include demo param when provided', () => {
      const { result } = renderHook(() => useNavigationFlow());

      act(() => {
        result.current.goToActivate(1, true);
      });

      expect(mockPush).toHaveBeenCalledWith({
        pathname: ROUTES.AUTH.ACTIVATE,
        params: { beneficiaryId: 1, demo: true },
      });
    });
  });

  describe('navigation shortcuts', () => {
    it('should navigate to dashboard', () => {
      const { result } = renderHook(() => useNavigationFlow());

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

      expect(mockReplace).toHaveBeenCalledWith(ROUTES.TABS.DASHBOARD);
    });

    it('should navigate to login', () => {
      const { result } = renderHook(() => useNavigationFlow());

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

      expect(mockReplace).toHaveBeenCalledWith(ROUTES.AUTH.LOGIN);
    });

    it('should navigate to add beneficiary', () => {
      const { result } = renderHook(() => useNavigationFlow());

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

      expect(mockPush).toHaveBeenCalledWith(ROUTES.AUTH.ADD_LOVED_ONE);
    });

    it('should navigate to profile', () => {
      const { result } = renderHook(() => useNavigationFlow());

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

      expect(mockPush).toHaveBeenCalledWith(ROUTES.TABS.PROFILE);
    });
  });
});
