import { describe, it, expect, vi, beforeEach } from 'vitest';
import { renderHook, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { useTenants } from './useTenants';
import { tenantClient } from '../api/tenantClient';

// Mock the API client
vi.mock('../api/tenantClient', () => ({
  tenantClient: {
    index: {
      $get: vi.fn(),
      $post: vi.fn()
    },
    ':id': {
      $put: vi.fn(),
      $delete: vi.fn()
    }
  }
}));

const createWrapper = () => {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: { retry: false },
      mutations: { retry: false }
    }
  });

  return ({ children }: { children: React.ReactNode }) => (
    <QueryClientProvider client={queryClient}>
      {children}
    </QueryClientProvider>
  );
};

describe('useTenants', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('should fetch tenants successfully', async () => {
    const mockResponse = {
      data: [
        { id: 1, name: 'Tenant 1', code: 'tenant1', status: 1 },
        { id: 2, name: 'Tenant 2', code: 'tenant2', status: 2 }
      ],
      pagination: { total: 2, page: 1, pageSize: 10 }
    };

    vi.mocked(tenantClient.index.$get).mockResolvedValue({
      status: 200,
      json: async () => mockResponse
    } as never);

    const { result } = renderHook(() => useTenants(), {
      wrapper: createWrapper()
    });

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

    expect(result.current.data).toEqual(mockResponse);
    expect(tenantClient.index.$get).toHaveBeenCalledWith({
      query: {
        page: 1,
        pageSize: 10,
        keyword: '',
        filters: undefined
      }
    });
  });

  it('should handle fetch error', async () => {
    vi.mocked(tenantClient.index.$get).mockResolvedValue({
      status: 500,
      json: async () => ({ error: 'Internal Server Error' })
    } as never);

    const { result } = renderHook(() => useTenants(), {
      wrapper: createWrapper()
    });

    await waitFor(() => expect(result.current.isError).toBe(true));
  });

  it('should use custom options', async () => {
    const mockResponse = {
      data: [],
      pagination: { total: 0, page: 2, pageSize: 20 }
    };

    vi.mocked(tenantClient.index.$get).mockResolvedValue({
      status: 200,
      json: async () => mockResponse
    } as never);

    const { result } = renderHook(
      () => useTenants({
        page: 2,
        pageSize: 20,
        keyword: 'test',
        filters: { status: 1 }
      }),
      {
        wrapper: createWrapper()
      }
    );

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

    expect(tenantClient.index.$get).toHaveBeenCalledWith({
      query: {
        page: 2,
        pageSize: 20,
        keyword: 'test',
        filters: JSON.stringify({ status: 1 })
      }
    });
  });
});