import { describe, it, expect, vi, beforeEach } from 'vitest';

// Mock the API client
const mockApiGet = vi.fn();
const mockApiPost = vi.fn();
const mockApiPut = vi.fn();
const mockApiDelete = vi.fn();

vi.mock('@/api/client', () => ({
  apiGet: (...args: any[]) => mockApiGet(...args),
  apiPost: (...args: any[]) => mockApiPost(...args),
  apiPut: (...args: any[]) => mockApiPut(...args),
  apiDelete: (...args: any[]) => mockApiDelete(...args),
}));

// Mock react-query
vi.mock('@tanstack/react-query', () => ({
  useQueryClient: () => ({
    invalidateQueries: vi.fn(),
  }),
  useQuery: vi.fn(),
  useMutation: vi.fn(({ mutationFn, onSuccess }) => ({
    mutateAsync: async (args: any) => {
      const result = await mutationFn(args);
      if (onSuccess) onSuccess();
      return result;
    },
    isPending: false,
  })),
}));

describe('Automation API Hooks', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  describe('useAutomations', () => {
    it('calls apiGet with correct endpoint', async () => {
      const { useAutomations } = await import('../automation');
      const { useQuery } = await import('@tanstack/react-query');

      (useQuery as any).mockImplementation(({ queryKey, queryFn }: any) => {
        expect(queryKey).toEqual(['automations']);
        queryFn();
        return { data: [], isLoading: false };
      });

      useAutomations();
      expect(mockApiGet).toHaveBeenCalledWith('/automation');
    });
  });

  describe('useAgents', () => {
    it('calls apiGet with correct endpoint', async () => {
      const { useAgents } = await import('../automation');
      const { useQuery } = await import('@tanstack/react-query');

      (useQuery as any).mockImplementation(({ queryKey, queryFn }: any) => {
        expect(queryKey).toEqual(['agents']);
        queryFn();
        return { data: [], isLoading: false };
      });

      useAgents();
      expect(mockApiGet).toHaveBeenCalledWith('/agents');
    });
  });

  describe('useCreateAutomation', () => {
    it('calls apiPost with correct endpoint', async () => {
      const { useCreateAutomation } = await import('../automation');
      const hook = useCreateAutomation();

      const data = { name: 'Test', trigger_type: 'manual' as const };
      await hook.mutateAsync(data);

      expect(mockApiPost).toHaveBeenCalledWith('/automation', data);
    });
  });

  describe('useCreateAgent', () => {
    it('calls apiPost with correct endpoint', async () => {
      const { useCreateAgent } = await import('../automation');
      const hook = useCreateAgent();

      const data = { name: 'Test Agent', llm_model: 'gpt-4' };
      await hook.mutateAsync(data);

      expect(mockApiPost).toHaveBeenCalledWith('/agents', data);
    });
  });

  describe('useExecuteAutomation', () => {
    it('calls apiPost with correct endpoint', async () => {
      const { useExecuteAutomation } = await import('../automation');
      const hook = useExecuteAutomation();

      await hook.mutateAsync('123');

      expect(mockApiPost).toHaveBeenCalledWith('/automation/123/execute');
    });
  });

  describe('useExecuteAgent', () => {
    it('calls apiPost with correct endpoint', async () => {
      const { useExecuteAgent } = await import('../automation');
      const hook = useExecuteAgent();

      await hook.mutateAsync('456');

      expect(mockApiPost).toHaveBeenCalledWith('/agents/456/execute');
    });
  });

  describe('useDeleteAutomation', () => {
    it('calls apiDelete with correct endpoint', async () => {
      const { useDeleteAutomation } = await import('../automation');
      const hook = useDeleteAutomation();

      await hook.mutateAsync('789');

      expect(mockApiDelete).toHaveBeenCalledWith('/automation/789');
    });
  });

  describe('useDeleteAgent', () => {
    it('calls apiDelete with correct endpoint', async () => {
      const { useDeleteAgent } = await import('../automation');
      const hook = useDeleteAgent();

      await hook.mutateAsync('012');

      expect(mockApiDelete).toHaveBeenCalledWith('/agents/012');
    });
  });

  describe('useSendAgentMessage', () => {
    it('calls apiPost with correct endpoint and body', async () => {
      const { useSendAgentMessage } = await import('../automation');
      const hook = useSendAgentMessage();

      await hook.mutateAsync({
        id: 'agent-1',
        toAgentName: 'target-agent',
        message: 'Hello there',
      });

      expect(mockApiPost).toHaveBeenCalledWith('/agents/agent-1/send-message', {
        to_agent_name: 'target-agent',
        message: 'Hello there',
      });
    });
  });

  describe('useMiniApps', () => {
    it('calls apiGet with correct endpoint', async () => {
      const { useMiniApps } = await import('../automation');
      const { useQuery } = await import('@tanstack/react-query');

      (useQuery as any).mockImplementation(({ queryKey, queryFn }: any) => {
        expect(queryKey).toEqual(['miniapps']);
        queryFn();
        return { data: [], isLoading: false };
      });

      useMiniApps();
      expect(mockApiGet).toHaveBeenCalledWith('/automation/miniapps');
    });
  });

  describe('useCreateMiniApp', () => {
    it('calls apiPost with correct endpoint', async () => {
      const { useCreateMiniApp } = await import('../automation');
      const hook = useCreateMiniApp();

      const data = { app_id: 'my-app', name: 'My App' };
      await hook.mutateAsync(data);

      expect(mockApiPost).toHaveBeenCalledWith('/automation/miniapps', data);
    });
  });

  describe('useDeleteMiniApp', () => {
    it('calls apiDelete with correct endpoint', async () => {
      const { useDeleteMiniApp } = await import('../automation');
      const hook = useDeleteMiniApp();

      await hook.mutateAsync('my-app');

      expect(mockApiDelete).toHaveBeenCalledWith('/automation/miniapps/my-app');
    });
  });
});
