/**
 * @ai-summary Tests for Community Stations React Query hooks
 */

import React, { ReactNode } from 'react';
import { renderHook, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import {
  useSubmitStation,
  useMySubmissions,
  useApprovedStations,
  usePendingSubmissions,
  useReviewStation,
} from '../../hooks/useCommunityStations';
import * as communityStationsApi from '../../api/community-stations.api';

// Mock the API
jest.mock('../../api/community-stations.api');

// Setup React Query test wrapper
const createTestQueryClient = () =>
  new QueryClient({
    defaultOptions: {
      queries: { retry: false },
      mutations: { retry: false },
    },
  });

const Wrapper = ({ children }: { children: ReactNode }) => {
  const testQueryClient = createTestQueryClient();
  return React.createElement(
    QueryClientProvider,
    { client: testQueryClient },
    children
  );
};

describe('Community Stations Hooks', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  describe('useSubmitStation', () => {
    it('should handle successful submission', async () => {
      const mockStation = {
        id: '1',
        submittedBy: 'user@example.com',
        name: 'Shell Downtown',
        address: '123 Main St',
        latitude: 39.7392,
        longitude: -104.9903,
        has93Octane: true,
        has93OctaneEthanolFree: false,
        status: 'pending',
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
      };

      jest.spyOn(communityStationsApi.communityStationsApi, 'submitStation').mockResolvedValueOnce(mockStation as any);

      const { result } = renderHook(() => useSubmitStation(), { wrapper: Wrapper });

      // Initially should be idle
      expect(result.current.isPending).toBe(false);
    });
  });

  describe('useMySubmissions', () => {
    it('should fetch user submissions', async () => {
      const mockSubmissions = [
        {
          id: '1',
          submittedBy: 'user@example.com',
          name: 'Shell Downtown',
          address: '123 Main St',
          latitude: 39.7392,
          longitude: -104.9903,
          has93Octane: true,
          has93OctaneEthanolFree: false,
          status: 'pending',
          createdAt: new Date().toISOString(),
          updatedAt: new Date().toISOString(),
        },
      ];

      jest
        .spyOn(communityStationsApi.communityStationsApi, 'getMySubmissions')
        .mockResolvedValueOnce(mockSubmissions as any);

      const { result } = renderHook(() => useMySubmissions(), { wrapper: Wrapper });

      // Initially should be loading
      expect(result.current.isLoading).toBe(true);

      // Wait for data to be loaded
      await waitFor(() => {
        expect(result.current.isLoading).toBe(false);
      });

      expect(result.current.data).toEqual(mockSubmissions);
    });
  });

  describe('useApprovedStations', () => {
    it('should fetch approved stations with pagination', async () => {
      const mockResponse = {
        stations: [
          {
            id: '1',
            submittedBy: 'user@example.com',
            name: 'Shell Downtown',
            address: '123 Main St',
            latitude: 39.7392,
            longitude: -104.9903,
            has93Octane: true,
            has93OctaneEthanolFree: false,
            status: 'approved',
            createdAt: new Date().toISOString(),
            updatedAt: new Date().toISOString(),
          },
        ],
        total: 1,
        page: 0,
        limit: 50,
      };

      jest
        .spyOn(communityStationsApi.communityStationsApi, 'getApprovedStations')
        .mockResolvedValueOnce(mockResponse as any);

      const { result } = renderHook(() => useApprovedStations(0, 50), { wrapper: Wrapper });

      await waitFor(() => {
        expect(result.current.isLoading).toBe(false);
      });

      expect(result.current.data).toEqual(mockResponse);
    });
  });

  describe('usePendingSubmissions', () => {
    it('should fetch pending submissions for admin', async () => {
      const mockResponse = {
        stations: [
          {
            id: '1',
            submittedBy: 'user@example.com',
            name: 'Chevron on Main',
            address: '456 Main St',
            latitude: 39.7392,
            longitude: -104.9903,
            has93Octane: true,
            has93OctaneEthanolFree: true,
            status: 'pending',
            createdAt: new Date().toISOString(),
            updatedAt: new Date().toISOString(),
          },
        ],
        total: 1,
        page: 0,
        limit: 50,
      };

      jest
        .spyOn(communityStationsApi.communityStationsApi, 'getPendingSubmissions')
        .mockResolvedValueOnce(mockResponse as any);

      const { result } = renderHook(() => usePendingSubmissions(0, 50), { wrapper: Wrapper });

      await waitFor(() => {
        expect(result.current.isLoading).toBe(false);
      });

      expect(result.current.data).toEqual(mockResponse);
    });
  });

  describe('useReviewStation', () => {
    it('should approve a station', async () => {
      const mockStation = {
        id: '1',
        status: 'approved',
      };

      jest
        .spyOn(communityStationsApi.communityStationsApi, 'reviewStation')
        .mockResolvedValueOnce(mockStation as any);

      const { result } = renderHook(() => useReviewStation(), { wrapper: Wrapper });

      expect(result.current.isPending).toBe(false);
    });

    it('should reject a station with reason', async () => {
      const mockStation = {
        id: '1',
        status: 'rejected',
        rejectionReason: 'Invalid address',
      };

      jest
        .spyOn(communityStationsApi.communityStationsApi, 'reviewStation')
        .mockResolvedValueOnce(mockStation as any);

      const { result } = renderHook(() => useReviewStation(), { wrapper: Wrapper });

      expect(result.current.isPending).toBe(false);
    });
  });
});
