/**
 * useConnectionManager Hook Tests
 *
 * Tests the connection manager hook including:
 * - Initial state
 * - handleNotConnectedClick behavior
 * - handleConnectionsChange behavior
 * - Dialog open/close state management
 */
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { renderHook, act } from '@testing-library/react';
import { useConnectionManager } from './useConnectionManager';
import { Integration } from '../types/integration';
import { TriggerAction } from './useCategorizedItems';

describe('useConnectionManager', () => {
  const mockIntegrations: Integration[] = [
    {
      slug: 'mailchimp',
      name: 'Mailchimp',
      description: 'Email marketing',
      category: 'email',
      icon: 'mailchimp.svg',
      connected: true,
      enabled: true,
      connections: [],
    },
    {
      slug: 'airtable',
      name: 'Airtable',
      description: 'Database',
      category: 'database',
      icon: 'airtable.svg',
      connected: false,
      enabled: true,
      connections: [],
    },
  ];

  const mockRefetchActions = vi.fn().mockResolvedValue(undefined);
  const mockRefetchIntegrations = vi.fn().mockResolvedValue(undefined);

  beforeEach(() => {
    vi.clearAllMocks();
  });

  // ==========================================================================
  // Initial State Tests
  // ==========================================================================

  describe('initial state', () => {
    it('returns connectionDialogOpen as false initially', () => {
      const { result } = renderHook(() =>
        useConnectionManager({
          integrations: mockIntegrations,
          refetchActions: mockRefetchActions,
          refetchIntegrations: mockRefetchIntegrations,
        }),
      );

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

    it('returns connectionDialogIntegration as null initially', () => {
      const { result } = renderHook(() =>
        useConnectionManager({
          integrations: mockIntegrations,
          refetchActions: mockRefetchActions,
          refetchIntegrations: mockRefetchIntegrations,
        }),
      );

      expect(result.current.connectionDialogIntegration).toBe(null);
    });
  });

  // ==========================================================================
  // handleNotConnectedClick Tests
  // ==========================================================================

  describe('handleNotConnectedClick', () => {
    it('opens dialog when clicking on not-connected item with matching integration', () => {
      const { result } = renderHook(() =>
        useConnectionManager({
          integrations: mockIntegrations,
          refetchActions: mockRefetchActions,
          refetchIntegrations: mockRefetchIntegrations,
        }),
      );

      const mockItem: TriggerAction = {
        id: 'add_to_mailchimp',
        name: 'Add to Mailchimp',
        description: 'Add subscriber to Mailchimp',
        icon: 'mailchimp',
        category: 'email',
        integration: 'mailchimp',
        isAvailable: true,
        availabilityReason: '',
        isConnected: false,
        requiresConnection: true,
      };

      act(() => {
        result.current.handleNotConnectedClick(mockItem);
      });

      expect(result.current.connectionDialogOpen).toBe(true);
      expect(result.current.connectionDialogIntegration).toEqual(mockIntegrations[0]);
    });

    it('sets correct integration when clicking on different integration', () => {
      const { result } = renderHook(() =>
        useConnectionManager({
          integrations: mockIntegrations,
          refetchActions: mockRefetchActions,
          refetchIntegrations: mockRefetchIntegrations,
        }),
      );

      const mockItem: TriggerAction = {
        id: 'create_record',
        name: 'Create Record',
        description: 'Create a record in Airtable',
        icon: 'airtable',
        category: 'database',
        integration: 'airtable',
        isAvailable: true,
        availabilityReason: '',
        isConnected: false,
        requiresConnection: true,
      };

      act(() => {
        result.current.handleNotConnectedClick(mockItem);
      });

      expect(result.current.connectionDialogOpen).toBe(true);
      expect(result.current.connectionDialogIntegration?.slug).toBe('airtable');
    });

    it('does not open dialog when integration is not found', () => {
      const { result } = renderHook(() =>
        useConnectionManager({
          integrations: mockIntegrations,
          refetchActions: mockRefetchActions,
          refetchIntegrations: mockRefetchIntegrations,
        }),
      );

      const mockItem: TriggerAction = {
        id: 'unknown_action',
        name: 'Unknown Action',
        description: 'Unknown action',
        icon: 'unknown',
        category: 'other',
        integration: 'nonexistent',
        isAvailable: true,
        availabilityReason: '',
        isConnected: false,
        requiresConnection: true,
      };

      act(() => {
        result.current.handleNotConnectedClick(mockItem);
      });

      expect(result.current.connectionDialogOpen).toBe(false);
      expect(result.current.connectionDialogIntegration).toBe(null);
    });

    it('updates integration reference when integrations array changes', () => {
      const { result, rerender } = renderHook(
        ({ integrations }) =>
          useConnectionManager({
            integrations,
            refetchActions: mockRefetchActions,
            refetchIntegrations: mockRefetchIntegrations,
          }),
        { initialProps: { integrations: mockIntegrations } },
      );

      // First click with original integrations
      const mockItem: TriggerAction = {
        id: 'add_to_mailchimp',
        name: 'Add to Mailchimp',
        description: 'Add subscriber to Mailchimp',
        icon: 'mailchimp',
        category: 'email',
        integration: 'mailchimp',
        isAvailable: true,
        availabilityReason: '',
        isConnected: false,
        requiresConnection: true,
      };

      act(() => {
        result.current.handleNotConnectedClick(mockItem);
      });

      expect(result.current.connectionDialogIntegration?.name).toBe('Mailchimp');

      // Rerender with updated integrations
      const updatedIntegrations = [
        { ...mockIntegrations[0], name: 'Mailchimp Updated' },
        mockIntegrations[1],
      ];

      rerender({ integrations: updatedIntegrations });

      // Close and reopen to get new reference
      act(() => {
        result.current.setConnectionDialogOpen(false);
      });

      act(() => {
        result.current.handleNotConnectedClick(mockItem);
      });

      expect(result.current.connectionDialogIntegration?.name).toBe('Mailchimp Updated');
    });
  });

  // ==========================================================================
  // handleConnectionsChange Tests
  // ==========================================================================

  describe('handleConnectionsChange', () => {
    it('calls both refetch functions', async () => {
      const { result } = renderHook(() =>
        useConnectionManager({
          integrations: mockIntegrations,
          refetchActions: mockRefetchActions,
          refetchIntegrations: mockRefetchIntegrations,
        }),
      );

      await act(async () => {
        await result.current.handleConnectionsChange();
      });

      expect(mockRefetchActions).toHaveBeenCalledTimes(1);
      expect(mockRefetchIntegrations).toHaveBeenCalledTimes(1);
    });

    it('calls refetch functions in parallel', async () => {
      const refetchActionsOrder: number[] = [];
      const refetchIntegrationsOrder: number[] = [];

      const slowRefetchActions = vi.fn().mockImplementation(async () => {
        refetchActionsOrder.push(Date.now());
        await new Promise((resolve) => setTimeout(resolve, 10));
      });

      const slowRefetchIntegrations = vi.fn().mockImplementation(async () => {
        refetchIntegrationsOrder.push(Date.now());
        await new Promise((resolve) => setTimeout(resolve, 10));
      });

      const { result } = renderHook(() =>
        useConnectionManager({
          integrations: mockIntegrations,
          refetchActions: slowRefetchActions,
          refetchIntegrations: slowRefetchIntegrations,
        }),
      );

      await act(async () => {
        await result.current.handleConnectionsChange();
      });

      expect(slowRefetchActions).toHaveBeenCalledTimes(1);
      expect(slowRefetchIntegrations).toHaveBeenCalledTimes(1);
    });

    it('waits for both refetch functions to complete', async () => {
      let actionsResolved = false;
      let integrationsResolved = false;

      const slowRefetchActions = vi.fn().mockImplementation(async () => {
        await new Promise((resolve) => setTimeout(resolve, 10));
        actionsResolved = true;
      });

      const slowRefetchIntegrations = vi.fn().mockImplementation(async () => {
        await new Promise((resolve) => setTimeout(resolve, 10));
        integrationsResolved = true;
      });

      const { result } = renderHook(() =>
        useConnectionManager({
          integrations: mockIntegrations,
          refetchActions: slowRefetchActions,
          refetchIntegrations: slowRefetchIntegrations,
        }),
      );

      await act(async () => {
        await result.current.handleConnectionsChange();
      });

      expect(actionsResolved).toBe(true);
      expect(integrationsResolved).toBe(true);
    });
  });

  // ==========================================================================
  // setConnectionDialogOpen Tests
  // ==========================================================================

  describe('setConnectionDialogOpen', () => {
    it('can open the dialog directly', () => {
      const { result } = renderHook(() =>
        useConnectionManager({
          integrations: mockIntegrations,
          refetchActions: mockRefetchActions,
          refetchIntegrations: mockRefetchIntegrations,
        }),
      );

      act(() => {
        result.current.setConnectionDialogOpen(true);
      });

      expect(result.current.connectionDialogOpen).toBe(true);
    });

    it('can close the dialog', () => {
      const { result } = renderHook(() =>
        useConnectionManager({
          integrations: mockIntegrations,
          refetchActions: mockRefetchActions,
          refetchIntegrations: mockRefetchIntegrations,
        }),
      );

      // Open then close
      act(() => {
        result.current.setConnectionDialogOpen(true);
      });

      act(() => {
        result.current.setConnectionDialogOpen(false);
      });

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