import { renderHook } from '@testing-library/react';
import { act } from 'react';
import { useButtonManagement } from './useButtonManagement';
import { WEBPUSH_BUTTON_TYPES } from '../../constants';

describe('useButtonManagement', () => {
  describe('Initialization', () => {
    it('should initialize with empty buttons array by default', () => {
      const { result } = renderHook(() => useButtonManagement());

      expect(result.current.buttons).toEqual([]);
      expect(result.current.isAddingButton).toBe(false);
      expect(result.current.buttonBeingAdded).toBe(null);
      expect(result.current.editingButtonIndex).toBe(null);
    });

    it('should initialize with provided initial buttons', () => {
      const initialButtons = [
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Button 1', url: 'https://example.com' },
      ];
      const { result } = renderHook(() => useButtonManagement(initialButtons));

      expect(result.current.buttons).toEqual(initialButtons);
    });
  });

  describe('Adding Buttons', () => {
    it('should handle adding primary button', () => {
      const { result } = renderHook(() => useButtonManagement());

      act(() => {
        result.current.handleAddPrimaryButton();
      });

      expect(result.current.isAddingButton).toBe(true);
      expect(result.current.buttonBeingAdded).toBe(WEBPUSH_BUTTON_TYPES.PRIMARY);
      expect(result.current.editingButtonIndex).toBe(null);
    });

    it('should handle adding secondary button', () => {
      const { result } = renderHook(() => useButtonManagement());

      act(() => {
        result.current.handleAddSecondaryButton();
      });

      expect(result.current.isAddingButton).toBe(true);
      expect(result.current.buttonBeingAdded).toBe(WEBPUSH_BUTTON_TYPES.SECONDARY);
      expect(result.current.editingButtonIndex).toBe(null);
    });
  });

  describe('Saving Buttons', () => {
    it('should add new button when not editing', () => {
      const { result } = renderHook(() => useButtonManagement());

      act(() => {
        result.current.handleAddPrimaryButton();
      });

      const buttonData = {
        type: WEBPUSH_BUTTON_TYPES.PRIMARY,
        text: 'Click Me',
        url: 'https://example.com',
      };

      act(() => {
        result.current.handleButtonSave(buttonData);
      });

      expect(result.current.buttons).toHaveLength(1);
      expect(result.current.buttons[0]).toEqual(expect.objectContaining(buttonData));
      expect(result.current.buttons[0].id).toBeDefined();
      expect(typeof result.current.buttons[0].id).toBe('string');
      expect(result.current.isAddingButton).toBe(false);
      expect(result.current.buttonBeingAdded).toBe(null);
      expect(result.current.editingButtonIndex).toBe(null);
    });

    it('should update existing button when editing', () => {
      const initialButtons = [
        { id: 'test-id-1', type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Old Text', url: 'https://old.com' },
      ];
      const { result } = renderHook(() => useButtonManagement(initialButtons));

      act(() => {
        result.current.handleButtonEdit(0);
      });

      const updatedButtonData = {
        type: WEBPUSH_BUTTON_TYPES.PRIMARY,
        text: 'New Text',
        url: 'https://new.com',
      };

      act(() => {
        result.current.handleButtonSave(updatedButtonData);
      });

      expect(result.current.buttons).toHaveLength(1);
      expect(result.current.buttons[0]).toEqual(expect.objectContaining(updatedButtonData));
      expect(result.current.buttons[0].id).toBe('test-id-1'); // ID should be preserved
      expect(result.current.isAddingButton).toBe(false);
      expect(result.current.buttonBeingAdded).toBe(null);
      expect(result.current.editingButtonIndex).toBe(null);
    });

    it('should add multiple buttons', () => {
      const { result } = renderHook(() => useButtonManagement());

      const button1 = {
        type: WEBPUSH_BUTTON_TYPES.PRIMARY,
        text: 'Button 1',
        url: 'https://example.com/1',
      };

      act(() => {
        result.current.handleAddPrimaryButton();
        result.current.handleButtonSave(button1);
      });

      const button2 = {
        type: WEBPUSH_BUTTON_TYPES.SECONDARY,
        text: 'Button 2',
        url: 'https://example.com/2',
      };

      act(() => {
        result.current.handleAddSecondaryButton();
        result.current.handleButtonSave(button2);
      });

      expect(result.current.buttons).toHaveLength(2);
      expect(result.current.buttons[0]).toEqual(expect.objectContaining(button1));
      expect(result.current.buttons[0].id).toBeDefined();
      expect(result.current.buttons[1]).toEqual(expect.objectContaining(button2));
      expect(result.current.buttons[1].id).toBeDefined();
      expect(result.current.buttons[0].id).not.toBe(result.current.buttons[1].id);
    });
  });

  describe('Canceling Button Operations', () => {
    it('should cancel adding button', () => {
      const { result } = renderHook(() => useButtonManagement());

      act(() => {
        result.current.handleAddPrimaryButton();
      });

      act(() => {
        result.current.handleButtonCancel();
      });

      expect(result.current.isAddingButton).toBe(false);
      expect(result.current.buttonBeingAdded).toBe(null);
      expect(result.current.editingButtonIndex).toBe(null);
    });

    it('should cancel editing button', () => {
      const initialButtons = [
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Button', url: 'https://example.com' },
      ];
      const { result } = renderHook(() => useButtonManagement(initialButtons));

      act(() => {
        result.current.handleButtonEdit(0);
      });

      act(() => {
        result.current.handleButtonCancel();
      });

      expect(result.current.isAddingButton).toBe(false);
      expect(result.current.buttonBeingAdded).toBe(null);
      expect(result.current.editingButtonIndex).toBe(null);
      expect(result.current.buttons).toEqual(initialButtons);
    });
  });

  describe('Editing Buttons', () => {
    it('should set up editing state for existing button', () => {
      const initialButtons = [
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Button', url: 'https://example.com' },
      ];
      const { result } = renderHook(() => useButtonManagement(initialButtons));

      act(() => {
        result.current.handleButtonEdit(0);
      });

      expect(result.current.isAddingButton).toBe(true);
      expect(result.current.buttonBeingAdded).toBe(WEBPUSH_BUTTON_TYPES.PRIMARY);
      expect(result.current.editingButtonIndex).toBe(0);
    });

    it('should set correct button type when editing', () => {
      const initialButtons = [
        { type: WEBPUSH_BUTTON_TYPES.SECONDARY, text: 'Button', url: 'https://example.com' },
      ];
      const { result } = renderHook(() => useButtonManagement(initialButtons));

      act(() => {
        result.current.handleButtonEdit(0);
      });

      expect(result.current.buttonBeingAdded).toBe(WEBPUSH_BUTTON_TYPES.SECONDARY);
    });
  });

  describe('Deleting Buttons', () => {
    it('should delete button at specified index', () => {
      const initialButtons = [
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Button 1', url: 'https://example.com/1' },
        { type: WEBPUSH_BUTTON_TYPES.SECONDARY, text: 'Button 2', url: 'https://example.com/2' },
      ];
      const { result } = renderHook(() => useButtonManagement(initialButtons));

      act(() => {
        result.current.handleButtonDelete(0);
      });

      expect(result.current.buttons).toHaveLength(1);
      expect(result.current.buttons[0]).toEqual(initialButtons[1]);
    });

    it('should delete last button', () => {
      const initialButtons = [
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Button', url: 'https://example.com' },
      ];
      const { result } = renderHook(() => useButtonManagement(initialButtons));

      act(() => {
        result.current.handleButtonDelete(0);
      });

      expect(result.current.buttons).toHaveLength(0);
    });

    it('should delete middle button correctly', () => {
      const initialButtons = [
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Button 1', url: 'https://example.com/1' },
        { type: WEBPUSH_BUTTON_TYPES.SECONDARY, text: 'Button 2', url: 'https://example.com/2' },
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Button 3', url: 'https://example.com/3' },
      ];
      const { result } = renderHook(() => useButtonManagement(initialButtons));

      act(() => {
        result.current.handleButtonDelete(1);
      });

      expect(result.current.buttons).toHaveLength(2);
      expect(result.current.buttons[0]).toEqual(initialButtons[0]);
      expect(result.current.buttons[1]).toEqual(initialButtons[2]);
    });
  });

  describe('Reordering Buttons', () => {
    it('should reorder buttons correctly', () => {
      const initialButtons = [
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Button 1', url: 'https://example.com/1' },
        { type: WEBPUSH_BUTTON_TYPES.SECONDARY, text: 'Button 2', url: 'https://example.com/2' },
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Button 3', url: 'https://example.com/3' },
      ];
      const { result } = renderHook(() => useButtonManagement(initialButtons));

      act(() => {
        result.current.handleButtonReorder(0, 2);
      });

      expect(result.current.buttons).toHaveLength(3);
      expect(result.current.buttons[0]).toEqual(initialButtons[1]);
      expect(result.current.buttons[1]).toEqual(initialButtons[2]);
      expect(result.current.buttons[2]).toEqual(initialButtons[0]);
    });

    it('should move button to beginning', () => {
      const initialButtons = [
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Button 1', url: 'https://example.com/1' },
        { type: WEBPUSH_BUTTON_TYPES.SECONDARY, text: 'Button 2', url: 'https://example.com/2' },
      ];
      const { result } = renderHook(() => useButtonManagement(initialButtons));

      act(() => {
        result.current.handleButtonReorder(1, 0);
      });

      expect(result.current.buttons[0]).toEqual(initialButtons[1]);
      expect(result.current.buttons[1]).toEqual(initialButtons[0]);
    });

    it('should move button to end', () => {
      const initialButtons = [
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Button 1', url: 'https://example.com/1' },
        { type: WEBPUSH_BUTTON_TYPES.SECONDARY, text: 'Button 2', url: 'https://example.com/2' },
      ];
      const { result } = renderHook(() => useButtonManagement(initialButtons));

      act(() => {
        result.current.handleButtonReorder(0, 1);
      });

      expect(result.current.buttons[0]).toEqual(initialButtons[1]);
      expect(result.current.buttons[1]).toEqual(initialButtons[0]);
    });
  });

  describe('Computed Values', () => {
    it('should return isAddFlow as true when adding new button', () => {
      const { result } = renderHook(() => useButtonManagement());

      act(() => {
        result.current.handleAddPrimaryButton();
      });

      expect(result.current.isAddFlow).toBe(true);
      expect(result.current.isEditFlow).toBe(false);
    });

    it('should return isEditFlow as true when editing existing button', () => {
      const initialButtons = [
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Button', url: 'https://example.com' },
      ];
      const { result } = renderHook(() => useButtonManagement(initialButtons));

      act(() => {
        result.current.handleButtonEdit(0);
      });

      expect(result.current.isAddFlow).toBe(false);
      expect(result.current.isEditFlow).toBe(true);
    });

    it('should show add primary button when no buttons exist', () => {
      const { result } = renderHook(() => useButtonManagement());

      expect(result.current.showAddPrimaryButton).toBe(true);
      expect(result.current.showAddSecondaryButton).toBe(false);
    });

    it('should show add secondary button when one button exists', () => {
      const initialButtons = [
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Button', url: 'https://example.com' },
      ];
      const { result } = renderHook(() => useButtonManagement(initialButtons));

      expect(result.current.showAddPrimaryButton).toBe(false);
      expect(result.current.showAddSecondaryButton).toBe(true);
    });

    it('should not show add buttons when adding primary button', () => {
      const { result } = renderHook(() => useButtonManagement());

      act(() => {
        result.current.handleAddPrimaryButton();
      });

      expect(result.current.showAddPrimaryButton).toBe(false);
      expect(result.current.showAddSecondaryButton).toBe(false);
    });

    it('should show disabled secondary during primary add flow', () => {
      const { result } = renderHook(() => useButtonManagement());

      act(() => {
        result.current.handleAddPrimaryButton();
      });

      expect(result.current.showDisabledSecondaryDuringPrimary).toBe(true);
      expect(result.current.disableSecondaryAddButton).toBe(true);
    });

    it('should not show disabled secondary when not in primary add flow', () => {
      const { result } = renderHook(() => useButtonManagement());

      expect(result.current.showDisabledSecondaryDuringPrimary).toBe(false);
      expect(result.current.disableSecondaryAddButton).toBe(false);
    });

    it('should not show disabled secondary when buttons already exist', () => {
      const initialButtons = [
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'Button', url: 'https://example.com' },
      ];
      const { result } = renderHook(() => useButtonManagement(initialButtons));

      expect(result.current.showDisabledSecondaryDuringPrimary).toBe(false);
      expect(result.current.disableSecondaryAddButton).toBe(false);
    });
  });

  describe('setButtons', () => {
    it('should allow direct button state update', () => {
      const { result } = renderHook(() => useButtonManagement());

      const newButtons = [
        { type: WEBPUSH_BUTTON_TYPES.PRIMARY, text: 'New Button', url: 'https://example.com' },
      ];

      act(() => {
        result.current.setButtons(newButtons);
      });

      expect(result.current.buttons).toEqual(newButtons);
    });
  });
});

