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

// Mock the platformEmailAddresses API module
vi.mock('../../api/platformEmailAddresses', () => ({
  getPlatformEmailAddresses: vi.fn(),
  getPlatformEmailAddress: vi.fn(),
  createPlatformEmailAddress: vi.fn(),
  updatePlatformEmailAddress: vi.fn(),
  deletePlatformEmailAddress: vi.fn(),
  removeLocalPlatformEmailAddress: vi.fn(),
  syncPlatformEmailAddress: vi.fn(),
  testImapConnection: vi.fn(),
  testSmtpConnection: vi.fn(),
  setAsDefault: vi.fn(),
  testMailServerConnection: vi.fn(),
  getMailServerAccounts: vi.fn(),
  getAvailableDomains: vi.fn(),
  getAssignableUsers: vi.fn(),
  importFromMailServer: vi.fn(),
}));

import {
  usePlatformEmailAddresses,
  usePlatformEmailAddress,
  useCreatePlatformEmailAddress,
  useUpdatePlatformEmailAddress,
  useDeletePlatformEmailAddress,
  useRemoveLocalPlatformEmailAddress,
  useSyncPlatformEmailAddress,
  useTestImapConnection,
  useTestSmtpConnection,
  useSetAsDefault,
  useTestMailServerConnection,
  useMailServerAccounts,
  useAvailableDomains,
  useAssignableUsers,
  useImportFromMailServer,
} from '../usePlatformEmailAddresses';

import * as platformEmailAddressesApi from '../../api/platformEmailAddresses';

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

  return function Wrapper({ children }: { children: React.ReactNode }) {
    return React.createElement(QueryClientProvider, { client: queryClient }, children);
  };
};

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

  describe('usePlatformEmailAddresses', () => {
    it('fetches all platform email addresses', async () => {
      const mockEmailAddresses = [
        {
          id: 1,
          display_name: 'Support',
          sender_name: 'Support Team',
          effective_sender_name: 'Support Team',
          local_part: 'support',
          domain: 'talova.net',
          email_address: 'support@talova.net',
          color: '#3b82f6',
          assigned_user: null,
          is_active: true,
          is_default: true,
          mail_server_synced: true,
          last_check_at: '2025-01-15T10:00:00Z',
          emails_processed_count: 42,
          created_at: '2025-01-01T00:00:00Z',
          updated_at: '2025-01-15T10:00:00Z',
        },
        {
          id: 2,
          display_name: 'Sales',
          sender_name: 'Sales Team',
          effective_sender_name: 'Sales Team',
          local_part: 'sales',
          domain: 'talova.net',
          email_address: 'sales@talova.net',
          color: '#10b981',
          assigned_user: {
            id: 5,
            email: 'john@example.com',
            first_name: 'John',
            last_name: 'Doe',
            full_name: 'John Doe',
          },
          is_active: true,
          is_default: false,
          mail_server_synced: false,
          emails_processed_count: 15,
          created_at: '2025-01-02T00:00:00Z',
          updated_at: '2025-01-10T12:00:00Z',
        },
      ];

      vi.mocked(platformEmailAddressesApi.getPlatformEmailAddresses).mockResolvedValue(
        mockEmailAddresses
      );

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

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

      expect(platformEmailAddressesApi.getPlatformEmailAddresses).toHaveBeenCalledTimes(1);
      expect(result.current.data).toEqual(mockEmailAddresses);
      expect(result.current.data).toHaveLength(2);
    });

    it('handles fetch error', async () => {
      vi.mocked(platformEmailAddressesApi.getPlatformEmailAddresses).mockRejectedValue(
        new Error('Network error')
      );

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

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

      expect(result.current.error).toBeInstanceOf(Error);
    });
  });

  describe('usePlatformEmailAddress', () => {
    it('fetches single platform email address by id', async () => {
      const mockEmailAddress = {
        id: 1,
        display_name: 'Support',
        sender_name: 'Support Team',
        effective_sender_name: 'Support Team',
        local_part: 'support',
        domain: 'talova.net',
        email_address: 'support@talova.net',
        color: '#3b82f6',
        is_active: true,
        is_default: true,
        mail_server_synced: true,
        last_sync_error: undefined,
        last_synced_at: '2025-01-15T09:00:00Z',
        last_check_at: '2025-01-15T10:00:00Z',
        emails_processed_count: 42,
        created_at: '2025-01-01T00:00:00Z',
        updated_at: '2025-01-15T10:00:00Z',
        imap_settings: {
          host: 'mail.talova.net',
          port: 993,
          use_ssl: true,
          username: 'support@talova.net',
          folder: 'INBOX',
        },
        smtp_settings: {
          host: 'mail.talova.net',
          port: 587,
          use_tls: true,
          use_ssl: false,
          username: 'support@talova.net',
        },
      };

      vi.mocked(platformEmailAddressesApi.getPlatformEmailAddress).mockResolvedValue(
        mockEmailAddress
      );

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

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

      expect(platformEmailAddressesApi.getPlatformEmailAddress).toHaveBeenCalledWith(1);
      expect(result.current.data).toEqual(mockEmailAddress);
      expect(result.current.data?.imap_settings).toBeDefined();
      expect(result.current.data?.smtp_settings).toBeDefined();
    });

    it('does not fetch when id is not provided', async () => {
      const { result } = renderHook(() => usePlatformEmailAddress(0), {
        wrapper: createWrapper(),
      });

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

      expect(platformEmailAddressesApi.getPlatformEmailAddress).not.toHaveBeenCalled();
    });

    it('handles fetch error for single email address', async () => {
      vi.mocked(platformEmailAddressesApi.getPlatformEmailAddress).mockRejectedValue(
        new Error('Not found')
      );

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

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

      expect(result.current.error).toBeInstanceOf(Error);
    });
  });

  describe('useCreatePlatformEmailAddress', () => {
    it('creates a new platform email address', async () => {
      const newEmailAddress = {
        display_name: 'New Support',
        sender_name: 'New Support Team',
        assigned_user_id: null,
        local_part: 'newsupport',
        domain: 'talova.net',
        color: '#ef4444',
        password: 'secure-password-123',
        is_active: true,
        is_default: false,
      };

      const createdEmailAddress = {
        id: 3,
        ...newEmailAddress,
        email_address: 'newsupport@talova.net',
        effective_sender_name: 'New Support Team',
        mail_server_synced: false,
        emails_processed_count: 0,
        created_at: '2025-01-15T12:00:00Z',
        updated_at: '2025-01-15T12:00:00Z',
      };

      vi.mocked(platformEmailAddressesApi.createPlatformEmailAddress).mockResolvedValue(
        createdEmailAddress as any
      );

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

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

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

      expect(platformEmailAddressesApi.createPlatformEmailAddress).toHaveBeenCalledWith(
        newEmailAddress
      );
    });

    it('invalidates queries after successful creation', async () => {
      const queryClient = new QueryClient({
        defaultOptions: {
          queries: { retry: false },
          mutations: { retry: false },
        },
      });

      const invalidateSpy = vi.spyOn(queryClient, 'invalidateQueries');

      vi.mocked(platformEmailAddressesApi.createPlatformEmailAddress).mockResolvedValue({
        id: 1,
      } as any);

      const wrapper = ({ children }: { children: React.ReactNode }) =>
        React.createElement(QueryClientProvider, { client: queryClient }, children);

      const { result } = renderHook(() => useCreatePlatformEmailAddress(), { wrapper });

      await act(async () => {
        await result.current.mutateAsync({
          display_name: 'Test',
          local_part: 'test',
          domain: 'talova.net',
          color: '#000000',
          password: 'password',
          is_active: true,
          is_default: false,
        });
      });

      expect(invalidateSpy).toHaveBeenCalledWith({
        queryKey: ['platformEmailAddresses'],
      });
    });

    it('handles creation error', async () => {
      vi.mocked(platformEmailAddressesApi.createPlatformEmailAddress).mockRejectedValue(
        new Error('Email address already exists')
      );

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

      await act(async () => {
        try {
          await result.current.mutateAsync({
            display_name: 'Duplicate',
            local_part: 'duplicate',
            domain: 'talova.net',
            color: '#000000',
            password: 'password',
            is_active: true,
            is_default: false,
          });
        } catch (error) {
          expect(error).toBeInstanceOf(Error);
        }
      });

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

  describe('useUpdatePlatformEmailAddress', () => {
    it('updates an existing platform email address', async () => {
      const updateData = {
        display_name: 'Updated Support',
        color: '#8b5cf6',
        is_active: false,
      };

      const updatedEmailAddress = {
        id: 1,
        ...updateData,
        sender_name: 'Support Team',
        effective_sender_name: 'Support Team',
        local_part: 'support',
        domain: 'talova.net',
        email_address: 'support@talova.net',
        is_default: true,
        mail_server_synced: true,
        emails_processed_count: 42,
        created_at: '2025-01-01T00:00:00Z',
        updated_at: '2025-01-15T14:00:00Z',
      };

      vi.mocked(platformEmailAddressesApi.updatePlatformEmailAddress).mockResolvedValue(
        updatedEmailAddress as any
      );

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

      await act(async () => {
        await result.current.mutateAsync({ id: 1, data: updateData });
      });

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

      expect(platformEmailAddressesApi.updatePlatformEmailAddress).toHaveBeenCalledWith(
        1,
        updateData
      );
    });

    it('updates password', async () => {
      const updateData = {
        password: 'new-secure-password',
      };

      vi.mocked(platformEmailAddressesApi.updatePlatformEmailAddress).mockResolvedValue({
        id: 1,
      } as any);

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

      await act(async () => {
        await result.current.mutateAsync({ id: 1, data: updateData });
      });

      expect(platformEmailAddressesApi.updatePlatformEmailAddress).toHaveBeenCalledWith(
        1,
        updateData
      );
    });

    it('updates assigned user', async () => {
      const updateData = {
        assigned_user_id: 10,
      };

      vi.mocked(platformEmailAddressesApi.updatePlatformEmailAddress).mockResolvedValue({
        id: 1,
      } as any);

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

      await act(async () => {
        await result.current.mutateAsync({ id: 1, data: updateData });
      });

      expect(platformEmailAddressesApi.updatePlatformEmailAddress).toHaveBeenCalledWith(
        1,
        updateData
      );
    });

    it('invalidates queries after successful update', async () => {
      const queryClient = new QueryClient({
        defaultOptions: {
          queries: { retry: false },
          mutations: { retry: false },
        },
      });

      const invalidateSpy = vi.spyOn(queryClient, 'invalidateQueries');

      vi.mocked(platformEmailAddressesApi.updatePlatformEmailAddress).mockResolvedValue({
        id: 1,
      } as any);

      const wrapper = ({ children }: { children: React.ReactNode }) =>
        React.createElement(QueryClientProvider, { client: queryClient }, children);

      const { result } = renderHook(() => useUpdatePlatformEmailAddress(), { wrapper });

      await act(async () => {
        await result.current.mutateAsync({ id: 1, data: { color: '#000000' } });
      });

      expect(invalidateSpy).toHaveBeenCalledWith({
        queryKey: ['platformEmailAddresses'],
      });
    });
  });

  describe('useDeletePlatformEmailAddress', () => {
    it('deletes a platform email address', async () => {
      vi.mocked(platformEmailAddressesApi.deletePlatformEmailAddress).mockResolvedValue();

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

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

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

      expect(platformEmailAddressesApi.deletePlatformEmailAddress).toHaveBeenCalledWith(1);
    });

    it('invalidates queries after successful deletion', async () => {
      const queryClient = new QueryClient({
        defaultOptions: {
          queries: { retry: false },
          mutations: { retry: false },
        },
      });

      const invalidateSpy = vi.spyOn(queryClient, 'invalidateQueries');

      vi.mocked(platformEmailAddressesApi.deletePlatformEmailAddress).mockResolvedValue();

      const wrapper = ({ children }: { children: React.ReactNode }) =>
        React.createElement(QueryClientProvider, { client: queryClient }, children);

      const { result } = renderHook(() => useDeletePlatformEmailAddress(), { wrapper });

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

      expect(invalidateSpy).toHaveBeenCalledWith({
        queryKey: ['platformEmailAddresses'],
      });
    });

    it('handles deletion error', async () => {
      vi.mocked(platformEmailAddressesApi.deletePlatformEmailAddress).mockRejectedValue(
        new Error('Cannot delete default email address')
      );

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

      await act(async () => {
        try {
          await result.current.mutateAsync(1);
        } catch (error) {
          expect(error).toBeInstanceOf(Error);
        }
      });

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

  describe('useRemoveLocalPlatformEmailAddress', () => {
    it('removes local email address', async () => {
      const mockResponse = {
        success: true,
        message: 'Email address removed from database',
      };

      vi.mocked(platformEmailAddressesApi.removeLocalPlatformEmailAddress).mockResolvedValue(
        mockResponse
      );

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

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

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

      expect(platformEmailAddressesApi.removeLocalPlatformEmailAddress).toHaveBeenCalledWith(1);
    });

    it('invalidates queries after successful removal', async () => {
      const queryClient = new QueryClient({
        defaultOptions: {
          queries: { retry: false },
          mutations: { retry: false },
        },
      });

      const invalidateSpy = vi.spyOn(queryClient, 'invalidateQueries');

      vi.mocked(platformEmailAddressesApi.removeLocalPlatformEmailAddress).mockResolvedValue({
        success: true,
        message: 'Removed',
      });

      const wrapper = ({ children }: { children: React.ReactNode }) =>
        React.createElement(QueryClientProvider, { client: queryClient }, children);

      const { result } = renderHook(() => useRemoveLocalPlatformEmailAddress(), { wrapper });

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

      expect(invalidateSpy).toHaveBeenCalledWith({
        queryKey: ['platformEmailAddresses'],
      });
    });
  });

  describe('useSyncPlatformEmailAddress', () => {
    it('syncs email address to mail server', async () => {
      const mockResponse = {
        success: true,
        message: 'Email address synced successfully',
        mail_server_synced: true,
        last_synced_at: '2025-01-15T15:00:00Z',
      };

      vi.mocked(platformEmailAddressesApi.syncPlatformEmailAddress).mockResolvedValue(
        mockResponse
      );

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

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

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

      expect(platformEmailAddressesApi.syncPlatformEmailAddress).toHaveBeenCalledWith(1);
    });

    it('handles sync error with error message', async () => {
      const mockResponse = {
        success: false,
        message: 'Failed to sync',
        last_sync_error: 'Connection refused',
      };

      vi.mocked(platformEmailAddressesApi.syncPlatformEmailAddress).mockResolvedValue(
        mockResponse
      );

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

      await act(async () => {
        const response = await result.current.mutateAsync(1);
        expect(response.success).toBe(false);
        expect(response.last_sync_error).toBe('Connection refused');
      });
    });

    it('invalidates queries after sync', async () => {
      const queryClient = new QueryClient({
        defaultOptions: {
          queries: { retry: false },
          mutations: { retry: false },
        },
      });

      const invalidateSpy = vi.spyOn(queryClient, 'invalidateQueries');

      vi.mocked(platformEmailAddressesApi.syncPlatformEmailAddress).mockResolvedValue({
        success: true,
        message: 'Synced',
      });

      const wrapper = ({ children }: { children: React.ReactNode }) =>
        React.createElement(QueryClientProvider, { client: queryClient }, children);

      const { result } = renderHook(() => useSyncPlatformEmailAddress(), { wrapper });

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

      expect(invalidateSpy).toHaveBeenCalledWith({
        queryKey: ['platformEmailAddresses'],
      });
    });
  });

  describe('useTestImapConnection', () => {
    it('tests IMAP connection successfully', async () => {
      const mockResponse = {
        success: true,
        message: 'IMAP connection successful',
      };

      vi.mocked(platformEmailAddressesApi.testImapConnection).mockResolvedValue(mockResponse);

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

      await act(async () => {
        const response = await result.current.mutateAsync(1);
        expect(response.success).toBe(true);
        expect(response.message).toBe('IMAP connection successful');
      });

      expect(platformEmailAddressesApi.testImapConnection).toHaveBeenCalledWith(1);
    });

    it('handles IMAP connection failure', async () => {
      const mockResponse = {
        success: false,
        message: 'Failed to connect to IMAP server',
      };

      vi.mocked(platformEmailAddressesApi.testImapConnection).mockResolvedValue(mockResponse);

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

      await act(async () => {
        const response = await result.current.mutateAsync(1);
        expect(response.success).toBe(false);
      });
    });

    it('does not invalidate queries', async () => {
      const queryClient = new QueryClient({
        defaultOptions: {
          queries: { retry: false },
          mutations: { retry: false },
        },
      });

      const invalidateSpy = vi.spyOn(queryClient, 'invalidateQueries');

      vi.mocked(platformEmailAddressesApi.testImapConnection).mockResolvedValue({
        success: true,
        message: 'Success',
      });

      const wrapper = ({ children }: { children: React.ReactNode }) =>
        React.createElement(QueryClientProvider, { client: queryClient }, children);

      const { result } = renderHook(() => useTestImapConnection(), { wrapper });

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

      expect(invalidateSpy).not.toHaveBeenCalled();
    });
  });

  describe('useTestSmtpConnection', () => {
    it('tests SMTP connection successfully', async () => {
      const mockResponse = {
        success: true,
        message: 'SMTP connection successful',
      };

      vi.mocked(platformEmailAddressesApi.testSmtpConnection).mockResolvedValue(mockResponse);

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

      await act(async () => {
        const response = await result.current.mutateAsync(1);
        expect(response.success).toBe(true);
        expect(response.message).toBe('SMTP connection successful');
      });

      expect(platformEmailAddressesApi.testSmtpConnection).toHaveBeenCalledWith(1);
    });

    it('handles SMTP connection failure', async () => {
      const mockResponse = {
        success: false,
        message: 'Authentication failed',
      };

      vi.mocked(platformEmailAddressesApi.testSmtpConnection).mockResolvedValue(mockResponse);

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

      await act(async () => {
        const response = await result.current.mutateAsync(1);
        expect(response.success).toBe(false);
        expect(response.message).toBe('Authentication failed');
      });
    });

    it('does not invalidate queries', async () => {
      const queryClient = new QueryClient({
        defaultOptions: {
          queries: { retry: false },
          mutations: { retry: false },
        },
      });

      const invalidateSpy = vi.spyOn(queryClient, 'invalidateQueries');

      vi.mocked(platformEmailAddressesApi.testSmtpConnection).mockResolvedValue({
        success: true,
        message: 'Success',
      });

      const wrapper = ({ children }: { children: React.ReactNode }) =>
        React.createElement(QueryClientProvider, { client: queryClient }, children);

      const { result } = renderHook(() => useTestSmtpConnection(), { wrapper });

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

      expect(invalidateSpy).not.toHaveBeenCalled();
    });
  });

  describe('useSetAsDefault', () => {
    it('sets email address as default', async () => {
      const mockResponse = {
        success: true,
        message: 'Email address set as default',
      };

      vi.mocked(platformEmailAddressesApi.setAsDefault).mockResolvedValue(mockResponse);

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

      await act(async () => {
        const response = await result.current.mutateAsync(1);
        expect(response.success).toBe(true);
      });

      expect(platformEmailAddressesApi.setAsDefault).toHaveBeenCalledWith(1);
    });

    it('invalidates queries after setting default', async () => {
      const queryClient = new QueryClient({
        defaultOptions: {
          queries: { retry: false },
          mutations: { retry: false },
        },
      });

      const invalidateSpy = vi.spyOn(queryClient, 'invalidateQueries');

      vi.mocked(platformEmailAddressesApi.setAsDefault).mockResolvedValue({
        success: true,
        message: 'Success',
      });

      const wrapper = ({ children }: { children: React.ReactNode }) =>
        React.createElement(QueryClientProvider, { client: queryClient }, children);

      const { result } = renderHook(() => useSetAsDefault(), { wrapper });

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

      expect(invalidateSpy).toHaveBeenCalledWith({
        queryKey: ['platformEmailAddresses'],
      });
    });
  });

  describe('useTestMailServerConnection', () => {
    it('tests mail server SSH connection successfully', async () => {
      const mockResponse = {
        success: true,
        message: 'SSH connection successful',
      };

      vi.mocked(platformEmailAddressesApi.testMailServerConnection).mockResolvedValue(
        mockResponse
      );

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

      await act(async () => {
        const response = await result.current.mutateAsync();
        expect(response.success).toBe(true);
        expect(response.message).toBe('SSH connection successful');
      });

      expect(platformEmailAddressesApi.testMailServerConnection).toHaveBeenCalledTimes(1);
    });

    it('handles SSH connection failure', async () => {
      const mockResponse = {
        success: false,
        message: 'SSH connection failed: Permission denied',
      };

      vi.mocked(platformEmailAddressesApi.testMailServerConnection).mockResolvedValue(
        mockResponse
      );

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

      await act(async () => {
        const response = await result.current.mutateAsync();
        expect(response.success).toBe(false);
      });
    });

    it('does not invalidate queries', async () => {
      const queryClient = new QueryClient({
        defaultOptions: {
          queries: { retry: false },
          mutations: { retry: false },
        },
      });

      const invalidateSpy = vi.spyOn(queryClient, 'invalidateQueries');

      vi.mocked(platformEmailAddressesApi.testMailServerConnection).mockResolvedValue({
        success: true,
        message: 'Success',
      });

      const wrapper = ({ children }: { children: React.ReactNode }) =>
        React.createElement(QueryClientProvider, { client: queryClient }, children);

      const { result } = renderHook(() => useTestMailServerConnection(), { wrapper });

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

      expect(invalidateSpy).not.toHaveBeenCalled();
    });
  });

  describe('useMailServerAccounts', () => {
    it('fetches mail server accounts', async () => {
      const mockResponse = {
        success: true,
        accounts: [
          {
            email: 'support@talova.net',
            raw_line: 'support@talova.net:{CRYPT}abcd1234...',
          },
          {
            email: 'sales@talova.net',
            raw_line: 'sales@talova.net:{CRYPT}efgh5678...',
          },
        ],
        count: 2,
      };

      vi.mocked(platformEmailAddressesApi.getMailServerAccounts).mockResolvedValue(
        mockResponse
      );

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

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

      expect(platformEmailAddressesApi.getMailServerAccounts).toHaveBeenCalledTimes(1);
      expect(result.current.data?.accounts).toHaveLength(2);
      expect(result.current.data?.count).toBe(2);
    });

    it('handles error when fetching mail server accounts', async () => {
      vi.mocked(platformEmailAddressesApi.getMailServerAccounts).mockRejectedValue(
        new Error('SSH connection failed')
      );

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

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

      expect(result.current.error).toBeInstanceOf(Error);
    });
  });

  describe('useAvailableDomains', () => {
    it('fetches available email domains', async () => {
      const mockResponse = {
        domains: [
          { value: 'talova.net', label: 'talova.net' },
          { value: 'smoothschedule.com', label: 'smoothschedule.com' },
        ],
      };

      vi.mocked(platformEmailAddressesApi.getAvailableDomains).mockResolvedValue(mockResponse);

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

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

      expect(platformEmailAddressesApi.getAvailableDomains).toHaveBeenCalledTimes(1);
      expect(result.current.data?.domains).toHaveLength(2);
      expect(result.current.data?.domains[0].value).toBe('talova.net');
    });

    it('handles empty domains list', async () => {
      const mockResponse = {
        domains: [],
      };

      vi.mocked(platformEmailAddressesApi.getAvailableDomains).mockResolvedValue(mockResponse);

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

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

      expect(result.current.data?.domains).toHaveLength(0);
    });
  });

  describe('useAssignableUsers', () => {
    it('fetches assignable users', async () => {
      const mockResponse = {
        users: [
          {
            id: 1,
            email: 'admin@example.com',
            first_name: 'Admin',
            last_name: 'User',
            full_name: 'Admin User',
            role: 'platform_superuser',
          },
          {
            id: 2,
            email: 'manager@example.com',
            first_name: 'Manager',
            last_name: 'User',
            full_name: 'Manager User',
            role: 'platform_manager',
          },
        ],
      };

      vi.mocked(platformEmailAddressesApi.getAssignableUsers).mockResolvedValue(mockResponse);

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

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

      expect(platformEmailAddressesApi.getAssignableUsers).toHaveBeenCalledTimes(1);
      expect(result.current.data?.users).toHaveLength(2);
      expect(result.current.data?.users[0].role).toBe('platform_superuser');
    });

    it('handles error when fetching assignable users', async () => {
      vi.mocked(platformEmailAddressesApi.getAssignableUsers).mockRejectedValue(
        new Error('Unauthorized')
      );

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

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

      expect(result.current.error).toBeInstanceOf(Error);
    });
  });

  describe('useImportFromMailServer', () => {
    it('imports email addresses from mail server', async () => {
      const mockResponse = {
        success: true,
        imported: [
          { id: 1, email: 'support@talova.net', display_name: 'Support' },
          { id: 2, email: 'sales@talova.net', display_name: 'Sales' },
        ],
        imported_count: 2,
        skipped: [
          { email: 'admin@talova.net', reason: 'Already exists' },
        ],
        skipped_count: 1,
        message: 'Imported 2 email addresses, skipped 1',
      };

      vi.mocked(platformEmailAddressesApi.importFromMailServer).mockResolvedValue(mockResponse);

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

      await act(async () => {
        const response = await result.current.mutateAsync();
        expect(response.success).toBe(true);
        expect(response.imported_count).toBe(2);
        expect(response.skipped_count).toBe(1);
      });

      expect(platformEmailAddressesApi.importFromMailServer).toHaveBeenCalledTimes(1);
    });

    it('handles import with no new addresses', async () => {
      const mockResponse = {
        success: true,
        imported: [],
        imported_count: 0,
        skipped: [
          { email: 'support@talova.net', reason: 'Already exists' },
          { email: 'sales@talova.net', reason: 'Already exists' },
        ],
        skipped_count: 2,
        message: 'No new email addresses to import',
      };

      vi.mocked(platformEmailAddressesApi.importFromMailServer).mockResolvedValue(mockResponse);

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

      await act(async () => {
        const response = await result.current.mutateAsync();
        expect(response.imported_count).toBe(0);
        expect(response.skipped_count).toBe(2);
      });
    });

    it('invalidates queries after successful import', async () => {
      const queryClient = new QueryClient({
        defaultOptions: {
          queries: { retry: false },
          mutations: { retry: false },
        },
      });

      const invalidateSpy = vi.spyOn(queryClient, 'invalidateQueries');

      vi.mocked(platformEmailAddressesApi.importFromMailServer).mockResolvedValue({
        success: true,
        imported: [],
        imported_count: 0,
        skipped: [],
        skipped_count: 0,
        message: 'Done',
      });

      const wrapper = ({ children }: { children: React.ReactNode }) =>
        React.createElement(QueryClientProvider, { client: queryClient }, children);

      const { result } = renderHook(() => useImportFromMailServer(), { wrapper });

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

      expect(invalidateSpy).toHaveBeenCalledWith({
        queryKey: ['platformEmailAddresses'],
      });
    });

    it('handles import error', async () => {
      vi.mocked(platformEmailAddressesApi.importFromMailServer).mockRejectedValue(
        new Error('Failed to connect to mail server')
      );

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

      await act(async () => {
        try {
          await result.current.mutateAsync();
        } catch (error) {
          expect(error).toBeInstanceOf(Error);
        }
      });

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