import { renderHook, act } from '@testing-library/react';
import usePlatformSync from '../usePlatformSync';
import {
  ANDROID, GIF, IMAGE, IOS, VIDEO,
} from '../../constants';
import { NONE } from '../../../Whatsapp/constants';

describe('usePlatformSync Hook', () => {
  // Mock functions
  const mockSetAndroidContent = jest.fn();
  const mockSetIosContent = jest.fn();
  const mockValidateTitle = jest.fn();
  const mockValidateMessage = jest.fn();
  const mockSetAndroidTitleError = jest.fn();
  const mockSetAndroidMessageError = jest.fn();
  const mockSetIosTitleError = jest.fn();
  const mockSetIosMessageError = jest.fn();
  const mockUpdateOnMpushImageReUpload = jest.fn();
  const mockUpdateOnMpushVideoReUpload = jest.fn();

  const defaultAndroidContent = {
    title: 'Android Title',
    message: 'Android Message',
    mediaType: IMAGE,
    buttons: [],
    actionOnClick: false,
    linkType: 'deep',
    deepLinkValue: '',
    externalLinkValue: '',
  };

  const defaultIosContent = {
    title: 'iOS Title',
    message: 'iOS Message',
    mediaType: IMAGE,
    buttons: [],
    actionOnClick: false,
    linkType: 'deep',
    deepLinkValue: '',
    externalLinkValue: '',
  };

  const defaultProps = {
    setAndroidContent: mockSetAndroidContent,
    setIosContent: mockSetIosContent,
    validateTitle: mockValidateTitle,
    validateMessage: mockValidateMessage,
    setAndroidTitleError: mockSetAndroidTitleError,
    setAndroidMessageError: mockSetAndroidMessageError,
    setIosTitleError: mockSetIosTitleError,
    setIosMessageError: mockSetIosMessageError,
    androidContent: defaultAndroidContent,
    iosContent: defaultIosContent,
    updateOnMpushImageReUpload: mockUpdateOnMpushImageReUpload,
    updateOnMpushVideoReUpload: mockUpdateOnMpushVideoReUpload,
  };

  beforeEach(() => {
    jest.clearAllMocks();
    mockValidateTitle.mockReturnValue('');
    mockValidateMessage.mockReturnValue('');

    // Make mock state setters actually execute functional updates
    mockSetAndroidContent.mockImplementation((updater) => {
      if (typeof updater === 'function') {
        updater(defaultAndroidContent);
      }
    });
    mockSetIosContent.mockImplementation((updater) => {
      if (typeof updater === 'function') {
        updater(defaultIosContent);
      }
    });
  });

  describe('Hook Initialization', () => {
    it('should initialize with all handler functions', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      expect(result.current.handleTitleChange).toBeDefined();
      expect(result.current.handleMessageChange).toBeDefined();
      expect(result.current.handleTagSelect).toBeDefined();
      expect(result.current.handleMediaTypeChange).toBeDefined();
      expect(result.current.handleButtonChange).toBeDefined();
      expect(result.current.handleActionOnClickChange).toBeDefined();
      expect(result.current.handleLinkTypeChange).toBeDefined();
    });
  });

  describe('handleTitleChange', () => {
    it('should update Android title when sync is disabled', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleTitleChange(ANDROID, 'New Android Title');
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        ...defaultAndroidContent,
        title: 'New Android Title',
      }));
      expect(mockSetAndroidTitleError).toHaveBeenCalledWith('');
      expect(mockValidateTitle).toHaveBeenCalledWith('New Android Title');
      expect(mockSetIosContent).not.toHaveBeenCalled();
    });

    it('should update iOS title when sync is disabled', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleTitleChange(IOS, 'New iOS Title');
      });

      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        ...defaultIosContent,
        title: 'New iOS Title',
      }));
      expect(mockSetIosTitleError).toHaveBeenCalledWith('');
      expect(mockValidateTitle).toHaveBeenCalledWith('New iOS Title');
      expect(mockSetAndroidContent).not.toHaveBeenCalled();
    });

    it('should sync title to iOS when changing Android title with sync enabled', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const { result } = renderHook(() => usePlatformSync(syncProps));

      act(() => {
        result.current.handleTitleChange(ANDROID, 'Synced Title');
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        ...defaultAndroidContent,
        title: 'Synced Title',
      }));
      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        title: 'Synced Title',
      }));
      expect(mockSetAndroidTitleError).toHaveBeenCalledWith('');
      expect(mockSetIosTitleError).toHaveBeenCalledWith('');
    });

    it('should sync title to Android when changing iOS title with sync enabled', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const { result } = renderHook(() => usePlatformSync(syncProps));

      act(() => {
        result.current.handleTitleChange(IOS, 'Synced iOS Title');
      });

      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        ...defaultIosContent,
        title: 'Synced iOS Title',
      }));
      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        title: 'Synced iOS Title',
      }));
      expect(mockSetIosTitleError).toHaveBeenCalledWith('');
      expect(mockSetAndroidTitleError).toHaveBeenCalledWith('');
    });

    it('should handle validation errors for title', () => {
      mockValidateTitle.mockReturnValue('Title is required');
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleTitleChange(ANDROID, '');
      });

      expect(mockSetAndroidTitleError).toHaveBeenCalledWith('Title is required');
    });
  });

  describe('handleMessageChange', () => {
    it('should update Android message when sync is disabled', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleMessageChange(ANDROID, 'New Android Message');
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        ...defaultAndroidContent,
        message: 'New Android Message',
      }));
      expect(mockSetAndroidMessageError).toHaveBeenCalledWith('');
      expect(mockValidateMessage).toHaveBeenCalledWith('New Android Message');
      expect(mockSetIosContent).not.toHaveBeenCalled();
    });

    it('should update iOS message when sync is disabled', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleMessageChange(IOS, 'New iOS Message');
      });

      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        ...defaultIosContent,
        message: 'New iOS Message',
      }));
      expect(mockSetIosMessageError).toHaveBeenCalledWith('');
      expect(mockValidateMessage).toHaveBeenCalledWith('New iOS Message');
      expect(mockSetAndroidContent).not.toHaveBeenCalled();
    });

    it('should sync message to iOS when changing Android message with sync enabled', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const { result } = renderHook(() => usePlatformSync(syncProps));

      act(() => {
        result.current.handleMessageChange(ANDROID, 'Synced Message');
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        ...defaultAndroidContent,
        message: 'Synced Message',
      }));
      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        message: 'Synced Message',
      }));
      expect(mockSetAndroidMessageError).toHaveBeenCalledWith('');
      expect(mockSetIosMessageError).toHaveBeenCalledWith('');
    });

    it('should sync message to Android when changing iOS message with sync enabled', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const { result } = renderHook(() => usePlatformSync(syncProps));

      act(() => {
        result.current.handleMessageChange(IOS, 'Synced iOS Message');
      });

      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        ...defaultIosContent,
        message: 'Synced iOS Message',
      }));
      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        message: 'Synced iOS Message',
      }));
      expect(mockSetIosMessageError).toHaveBeenCalledWith('');
      expect(mockSetAndroidMessageError).toHaveBeenCalledWith('');
    });

    it('should handle validation errors for message', () => {
      mockValidateMessage.mockReturnValue('Message is required');
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleMessageChange(ANDROID, '');
      });

      expect(mockSetAndroidMessageError).toHaveBeenCalledWith('Message is required');
    });
  });

  describe('handleMediaTypeChange', () => {
    describe('Android Platform', () => {
      it('should update Android media type when sync is disabled', () => {
        const { result } = renderHook(() => usePlatformSync(defaultProps));

        act(() => {
          result.current.handleMediaTypeChange(ANDROID, VIDEO);
        });

        expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
          ...defaultAndroidContent,
          mediaType: VIDEO,
        }));
        expect(mockSetIosContent).not.toHaveBeenCalled();
      });

      it('should clear image data when switching from IMAGE to VIDEO on Android', () => {
        const propsWithImageContent = {
          ...defaultProps,
          androidContent: { ...defaultAndroidContent, mediaType: IMAGE },
        };

        mockSetAndroidContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithImageContent.androidContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithImageContent));

        act(() => {
          result.current.handleMediaTypeChange(ANDROID, VIDEO);
        });

        expect(mockUpdateOnMpushImageReUpload).toHaveBeenCalled();
        expect(mockUpdateOnMpushVideoReUpload).not.toHaveBeenCalled();
      });

      it('should clear image data when switching from IMAGE to GIF on Android', () => {
        const propsWithImageContent = {
          ...defaultProps,
          androidContent: { ...defaultAndroidContent, mediaType: IMAGE },
        };

        mockSetAndroidContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithImageContent.androidContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithImageContent));

        act(() => {
          result.current.handleMediaTypeChange(ANDROID, GIF);
        });

        expect(mockUpdateOnMpushImageReUpload).toHaveBeenCalled();
        expect(mockUpdateOnMpushVideoReUpload).not.toHaveBeenCalled();
      });

      it('should clear video data when switching from VIDEO to IMAGE on Android', () => {
        const propsWithVideoContent = {
          ...defaultProps,
          androidContent: { ...defaultAndroidContent, mediaType: VIDEO },
        };

        mockSetAndroidContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithVideoContent.androidContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithVideoContent));

        act(() => {
          result.current.handleMediaTypeChange(ANDROID, IMAGE);
        });

        expect(mockUpdateOnMpushVideoReUpload).toHaveBeenCalled();
        expect(mockUpdateOnMpushImageReUpload).not.toHaveBeenCalled();
      });

      it('should clear video data when switching from GIF to IMAGE on Android', () => {
        const propsWithGifContent = {
          ...defaultProps,
          androidContent: { ...defaultAndroidContent, mediaType: GIF },
        };

        mockSetAndroidContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithGifContent.androidContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithGifContent));

        act(() => {
          result.current.handleMediaTypeChange(ANDROID, IMAGE);
        });

        expect(mockUpdateOnMpushVideoReUpload).toHaveBeenCalled();
        expect(mockUpdateOnMpushImageReUpload).not.toHaveBeenCalled();
      });

      it('should clear video data when switching from VIDEO to GIF on Android (Line 151)', () => {
        const propsWithVideoContent = {
          ...defaultProps,
          androidContent: { ...defaultAndroidContent, mediaType: VIDEO },
        };

        mockSetAndroidContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithVideoContent.androidContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithVideoContent));

        act(() => {
          result.current.handleMediaTypeChange(ANDROID, GIF);
        });

        expect(mockUpdateOnMpushVideoReUpload).toHaveBeenCalled();
        expect(mockUpdateOnMpushImageReUpload).not.toHaveBeenCalled();
      });

      it('should clear video data when switching from GIF to VIDEO on Android (Line 151)', () => {
        const propsWithGifContent = {
          ...defaultProps,
          androidContent: { ...defaultAndroidContent, mediaType: GIF },
        };

        mockSetAndroidContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithGifContent.androidContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithGifContent));

        act(() => {
          result.current.handleMediaTypeChange(ANDROID, VIDEO);
        });

        expect(mockUpdateOnMpushVideoReUpload).toHaveBeenCalled();
        expect(mockUpdateOnMpushImageReUpload).not.toHaveBeenCalled();
      });

      it('should clear video data when switching from VIDEO to NONE on Android', () => {
        const propsWithVideoContent = {
          ...defaultProps,
          androidContent: { ...defaultAndroidContent, mediaType: VIDEO },
        };

        mockSetAndroidContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithVideoContent.androidContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithVideoContent));

        act(() => {
          result.current.handleMediaTypeChange(ANDROID, NONE);
        });

        expect(mockUpdateOnMpushVideoReUpload).toHaveBeenCalled();
        expect(mockUpdateOnMpushImageReUpload).not.toHaveBeenCalled();
      });

      it('should clear video data when switching from GIF to NONE on Android', () => {
        const propsWithGifContent = {
          ...defaultProps,
          androidContent: { ...defaultAndroidContent, mediaType: GIF },
        };

        mockSetAndroidContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithGifContent.androidContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithGifContent));

        act(() => {
          result.current.handleMediaTypeChange(ANDROID, NONE);
        });

        expect(mockUpdateOnMpushVideoReUpload).toHaveBeenCalled();
        expect(mockUpdateOnMpushImageReUpload).not.toHaveBeenCalled();
      });

      it('should not clear data when switching to same media type on Android', () => {
        const propsWithVideoContent = {
          ...defaultProps,
          androidContent: { ...defaultAndroidContent, mediaType: VIDEO },
        };

        mockSetAndroidContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithVideoContent.androidContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithVideoContent));

        act(() => {
          result.current.handleMediaTypeChange(ANDROID, VIDEO);
        });

        expect(mockUpdateOnMpushVideoReUpload).not.toHaveBeenCalled();
        expect(mockUpdateOnMpushImageReUpload).not.toHaveBeenCalled();
      });
    });

    describe('iOS Platform', () => {
      it('should update iOS media type when sync is disabled', () => {
        const { result } = renderHook(() => usePlatformSync(defaultProps));

        act(() => {
          result.current.handleMediaTypeChange(IOS, VIDEO);
        });

        expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
          ...defaultIosContent,
          mediaType: VIDEO,
        }));
        expect(mockSetAndroidContent).not.toHaveBeenCalled();
      });

      it('should clear image data when switching from IMAGE to VIDEO on iOS', () => {
        const propsWithImageContent = {
          ...defaultProps,
          iosContent: { ...defaultIosContent, mediaType: IMAGE },
        };

        mockSetIosContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithImageContent.iosContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithImageContent));

        act(() => {
          result.current.handleMediaTypeChange(IOS, VIDEO);
        });

        expect(mockUpdateOnMpushImageReUpload).toHaveBeenCalled();
        expect(mockUpdateOnMpushVideoReUpload).not.toHaveBeenCalled();
      });

      it('should clear image data when switching from IMAGE to GIF on iOS', () => {
        const propsWithImageContent = {
          ...defaultProps,
          iosContent: { ...defaultIosContent, mediaType: IMAGE },
        };

        mockSetIosContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithImageContent.iosContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithImageContent));

        act(() => {
          result.current.handleMediaTypeChange(IOS, GIF);
        });

        expect(mockUpdateOnMpushImageReUpload).toHaveBeenCalled();
        expect(mockUpdateOnMpushVideoReUpload).not.toHaveBeenCalled();
      });

      it('should clear video data when switching from VIDEO to IMAGE on iOS', () => {
        const propsWithVideoContent = {
          ...defaultProps,
          iosContent: { ...defaultIosContent, mediaType: VIDEO },
        };

        mockSetIosContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithVideoContent.iosContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithVideoContent));

        act(() => {
          result.current.handleMediaTypeChange(IOS, IMAGE);
        });

        expect(mockUpdateOnMpushVideoReUpload).toHaveBeenCalled();
        expect(mockUpdateOnMpushImageReUpload).not.toHaveBeenCalled();
      });

      it('should clear video data when switching from GIF to IMAGE on iOS', () => {
        const propsWithGifContent = {
          ...defaultProps,
          iosContent: { ...defaultIosContent, mediaType: GIF },
        };

        mockSetIosContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithGifContent.iosContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithGifContent));

        act(() => {
          result.current.handleMediaTypeChange(IOS, IMAGE);
        });

        expect(mockUpdateOnMpushVideoReUpload).toHaveBeenCalled();
        expect(mockUpdateOnMpushImageReUpload).not.toHaveBeenCalled();
      });

      it('should clear video data when switching from VIDEO to GIF on iOS (Line 151)', () => {
        const propsWithVideoContent = {
          ...defaultProps,
          iosContent: { ...defaultIosContent, mediaType: VIDEO },
        };

        mockSetIosContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithVideoContent.iosContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithVideoContent));

        act(() => {
          result.current.handleMediaTypeChange(IOS, GIF);
        });

        expect(mockUpdateOnMpushVideoReUpload).toHaveBeenCalled();
        expect(mockUpdateOnMpushImageReUpload).not.toHaveBeenCalled();
      });

      it('should clear video data when switching from GIF to VIDEO on iOS (Line 151)', () => {
        const propsWithGifContent = {
          ...defaultProps,
          iosContent: { ...defaultIosContent, mediaType: GIF },
        };

        mockSetIosContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithGifContent.iosContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithGifContent));

        act(() => {
          result.current.handleMediaTypeChange(IOS, VIDEO);
        });

        expect(mockUpdateOnMpushVideoReUpload).toHaveBeenCalled();
        expect(mockUpdateOnMpushImageReUpload).not.toHaveBeenCalled();
      });

      it('should not clear data when switching to same media type on iOS', () => {
        const propsWithVideoContent = {
          ...defaultProps,
          iosContent: { ...defaultIosContent, mediaType: VIDEO },
        };

        mockSetIosContent.mockImplementation((updater) => {
          if (typeof updater === 'function') {
            updater(propsWithVideoContent.iosContent);
          }
        });

        const { result } = renderHook(() => usePlatformSync(propsWithVideoContent));

        act(() => {
          result.current.handleMediaTypeChange(IOS, VIDEO);
        });

        expect(mockUpdateOnMpushVideoReUpload).not.toHaveBeenCalled();
        expect(mockUpdateOnMpushImageReUpload).not.toHaveBeenCalled();
      });
    });

    describe('Sync Behavior', () => {
      it('should sync media type to iOS when changing Android media type with sync enabled', () => {
        const syncProps = { ...defaultProps, sameContent: true };
        const { result } = renderHook(() => usePlatformSync(syncProps));

        act(() => {
          result.current.handleMediaTypeChange(ANDROID, VIDEO);
        });

        expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
          mediaType: VIDEO,
        }));
        expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
          mediaType: VIDEO,
        }));
      });

      it('should sync media type to Android when changing iOS media type with sync enabled', () => {
        const syncProps = { ...defaultProps, sameContent: true };
        const { result } = renderHook(() => usePlatformSync(syncProps));

        act(() => {
          result.current.handleMediaTypeChange(IOS, GIF);
        });

        expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
          mediaType: GIF,
        }));
        expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
          mediaType: GIF,
        }));
      });
    });
  });

  describe('handleTagSelect', () => {
    it('should add tag to Android title when sync is disabled', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleTagSelect(ANDROID, 'USER_NAME', true);
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        title: 'Android Title{{USER_NAME}}',
      }));
      expect(mockSetAndroidTitleError).toHaveBeenCalledWith('');
      expect(mockSetIosContent).not.toHaveBeenCalled();
    });

    it('should add tag to iOS title when sync is disabled', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleTagSelect(IOS, 'USER_NAME', true);
      });

      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        title: 'iOS Title{{USER_NAME}}',
      }));
      expect(mockSetIosTitleError).toHaveBeenCalledWith('');
      expect(mockSetAndroidContent).not.toHaveBeenCalled();
    });

    it('should add tag to Android message when sync is disabled', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleTagSelect(ANDROID, 'USER_NAME', false);
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        message: 'Android Message{{USER_NAME}}',
      }));
      expect(mockSetAndroidMessageError).toHaveBeenCalledWith('');
      expect(mockSetIosContent).not.toHaveBeenCalled();
    });

    it('should add tag to iOS message when sync is disabled', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleTagSelect(IOS, 'USER_NAME', false);
      });

      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        message: 'iOS Message{{USER_NAME}}',
      }));
      expect(mockSetIosMessageError).toHaveBeenCalledWith('');
      expect(mockSetAndroidContent).not.toHaveBeenCalled();
    });

    it('should sync tag to iOS when adding to Android title with sync enabled', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const { result } = renderHook(() => usePlatformSync(syncProps));

      act(() => {
        result.current.handleTagSelect(ANDROID, 'USER_NAME', true);
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        title: 'Android Title{{USER_NAME}}',
      }));
      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        title: 'Android Title{{USER_NAME}}',
      }));
    });

    it('should sync tag to Android when adding to iOS message with sync enabled', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const { result } = renderHook(() => usePlatformSync(syncProps));

      act(() => {
        result.current.handleTagSelect(IOS, 'USER_NAME', false);
      });

      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        message: 'iOS Message{{USER_NAME}}',
      }));
      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        message: 'iOS Message{{USER_NAME}}',
      }));
    });
  });

  describe('handleButtonChange', () => {
    const testButtons = [
      {
        id: 1, text: 'Button 1', action: 'url', value: 'https://example.com',
      },
      {
        id: 2, text: 'Button 2', action: 'deeplink', value: 'myapp://open',
      },
    ];

    it('should update Android buttons when sync is disabled', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleButtonChange(ANDROID, testButtons);
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        buttons: testButtons,
      }));
      expect(mockSetIosContent).not.toHaveBeenCalled();
    });

    it('should update iOS buttons when sync is disabled', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleButtonChange(IOS, testButtons);
      });

      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        buttons: testButtons,
      }));
      expect(mockSetAndroidContent).not.toHaveBeenCalled();
    });

    it('should sync buttons to iOS when changing Android buttons with sync enabled', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const { result } = renderHook(() => usePlatformSync(syncProps));

      act(() => {
        result.current.handleButtonChange(ANDROID, testButtons);
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        buttons: testButtons,
      }));
      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        buttons: expect.arrayContaining([
          expect.objectContaining({ platform: IOS }),
          expect.objectContaining({ platform: IOS }),
        ]),
      }));
    });

    it('should sync buttons to Android when changing iOS buttons with sync enabled', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const { result } = renderHook(() => usePlatformSync(syncProps));

      act(() => {
        result.current.handleButtonChange(IOS, testButtons);
      });

      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        buttons: testButtons,
      }));
      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        buttons: expect.arrayContaining([
          expect.objectContaining({ platform: ANDROID }),
          expect.objectContaining({ platform: ANDROID }),
        ]),
      }));
    });

    // Additional test cases for line 49 coverage - Array.isArray(sourceContent.buttons)
    it('should handle non-array buttons during sync - null buttons (Line 49)', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const propsWithNullButtons = {
        ...syncProps,
        androidContent: { ...defaultAndroidContent, buttons: null },
      };

      const { result } = renderHook(() => usePlatformSync(propsWithNullButtons));

      act(() => {
        result.current.handleTitleChange(ANDROID, 'Test Title');
      });

      // When syncing, if buttons is null, it should default to empty array
      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        title: 'Test Title',
        buttons: [],
      }));
    });

    it('should handle non-array buttons during sync - undefined buttons (Line 49)', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const propsWithUndefinedButtons = {
        ...syncProps,
        androidContent: { ...defaultAndroidContent, buttons: undefined },
      };

      const { result } = renderHook(() => usePlatformSync(propsWithUndefinedButtons));

      act(() => {
        result.current.handleMessageChange(ANDROID, 'Test Message');
      });

      // When syncing, if buttons is undefined, it should default to empty array
      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        message: 'Test Message',
        buttons: [],
      }));
    });

    it('should handle non-array buttons during sync - string buttons (Line 49)', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const propsWithStringButtons = {
        ...syncProps,
        androidContent: { ...defaultAndroidContent, buttons: 'invalid-buttons' },
      };

      const { result } = renderHook(() => usePlatformSync(propsWithStringButtons));

      act(() => {
        result.current.handleActionOnClickChange(ANDROID, true);
      });

      // When syncing, if buttons is not an array, it should default to empty array
      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        actionOnClick: true,
        buttons: [],
      }));
    });

    it('should handle non-array buttons during sync - object buttons (Line 49)', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const propsWithObjectButtons = {
        ...syncProps,
        iosContent: { ...defaultIosContent, buttons: { invalid: 'object' } },
      };

      const { result } = renderHook(() => usePlatformSync(propsWithObjectButtons));

      act(() => {
        result.current.handleLinkTypeChange(IOS, 'external');
      });

      // When syncing, if buttons is not an array, it should default to empty array
      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        linkType: 'external',
        buttons: [],
      }));
    });
  });

  describe('handleActionOnClickChange', () => {
    it('should update Android actionOnClick when sync is disabled', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleActionOnClickChange(ANDROID, true);
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        actionOnClick: true,
      }));
      expect(mockSetIosContent).not.toHaveBeenCalled();
    });

    it('should update iOS actionOnClick when sync is disabled', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleActionOnClickChange(IOS, true);
      });

      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        actionOnClick: true,
      }));
      expect(mockSetAndroidContent).not.toHaveBeenCalled();
    });

    it('should sync actionOnClick to iOS when changing Android with sync enabled', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const { result } = renderHook(() => usePlatformSync(syncProps));

      act(() => {
        result.current.handleActionOnClickChange(ANDROID, true);
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        actionOnClick: true,
      }));
      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        actionOnClick: true,
      }));
    });

    it('should sync actionOnClick to Android when changing iOS with sync enabled', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const { result } = renderHook(() => usePlatformSync(syncProps));

      act(() => {
        result.current.handleActionOnClickChange(IOS, false);
      });

      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        actionOnClick: false,
      }));
      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        actionOnClick: false,
      }));
    });
  });

  describe('handleLinkTypeChange', () => {
    it('should update Android linkType when sync is disabled', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleLinkTypeChange(ANDROID, 'external');
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        linkType: 'external',
        deepLinkValue: '',
        externalLinkValue: '',
      }));
      expect(mockSetIosContent).not.toHaveBeenCalled();
    });

    it('should update iOS linkType when sync is disabled', () => {
      const { result } = renderHook(() => usePlatformSync(defaultProps));

      act(() => {
        result.current.handleLinkTypeChange(IOS, 'external');
      });

      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        linkType: 'external',
        deepLinkValue: '',
        externalLinkValue: '',
      }));
      expect(mockSetAndroidContent).not.toHaveBeenCalled();
    });

    it('should sync linkType to iOS when changing Android with sync enabled', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const { result } = renderHook(() => usePlatformSync(syncProps));

      act(() => {
        result.current.handleLinkTypeChange(ANDROID, 'external');
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        linkType: 'external',
        deepLinkValue: '',
        externalLinkValue: '',
      }));
      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        linkType: 'external',
        deepLinkValue: '',
        externalLinkValue: '',
      }));
    });

    it('should sync linkType to Android when changing iOS with sync enabled', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const { result } = renderHook(() => usePlatformSync(syncProps));

      act(() => {
        result.current.handleLinkTypeChange(IOS, 'deep');
      });

      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        linkType: 'deep',
        deepLinkValue: '',
        externalLinkValue: '',
      }));
      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        linkType: 'deep',
        deepLinkValue: '',
        externalLinkValue: '',
      }));
    });

    it('should clear link values when switching link types', () => {
      const propsWithLinkValues = {
        ...defaultProps,
        androidContent: {
          ...defaultAndroidContent,
          linkType: 'deep',
          deepLinkValue: 'myapp://deeplink',
          externalLinkValue: 'https://example.com',
        },
      };
      const { result } = renderHook(() => usePlatformSync(propsWithLinkValues));

      act(() => {
        result.current.handleLinkTypeChange(ANDROID, 'external');
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        linkType: 'external',
        deepLinkValue: '',
        externalLinkValue: '',
      }));
    });
  });

  describe('Edge Cases', () => {
    it('should handle empty content gracefully', () => {
      const propsWithEmptyContent = {
        ...defaultProps,
        androidContent: {},
        iosContent: {},
      };
      const { result } = renderHook(() => usePlatformSync(propsWithEmptyContent));

      act(() => {
        result.current.handleTitleChange(ANDROID, 'Test Title');
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        title: 'Test Title',
      }));
      expect(mockSetAndroidTitleError).toHaveBeenCalledWith('');
    });

    it('should handle validation functions gracefully', () => {
      const propsWithValidation = {
        ...defaultProps,
        validateTitle: jest.fn().mockReturnValue(''),
        validateMessage: jest.fn().mockReturnValue(''),
      };

      const { result } = renderHook(() => usePlatformSync(propsWithValidation));

      expect(() => {
        act(() => {
          result.current.handleTitleChange(ANDROID, 'Test Title');
        });
      }).not.toThrow();

      expect(propsWithValidation.validateTitle).toHaveBeenCalledWith('Test Title');
    });

    it('should handle undefined media type gracefully', () => {
      const propsWithUndefinedMediaType = {
        ...defaultProps,
        androidContent: { ...defaultAndroidContent, mediaType: undefined },
      };
      const { result } = renderHook(() => usePlatformSync(propsWithUndefinedMediaType));

      act(() => {
        result.current.handleMediaTypeChange(ANDROID, VIDEO);
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        ...defaultAndroidContent,
        mediaType: VIDEO,
      }));
    });

    it('should handle button array with platform-specific properties', () => {
      const buttonsWithPlatform = [
        { id: 1, text: 'Button 1', platform: ANDROID },
        { id: 2, text: 'Button 2', platform: IOS },
      ];
      const syncProps = { ...defaultProps, sameContent: true };
      const { result } = renderHook(() => usePlatformSync(syncProps));

      act(() => {
        result.current.handleButtonChange(ANDROID, buttonsWithPlatform);
      });

      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        buttons: buttonsWithPlatform,
      }));
      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        buttons: expect.arrayContaining([
          expect.objectContaining({ platform: IOS }),
          expect.objectContaining({ platform: IOS }),
        ]),
      }));
    });
  });

  // Additional test case for line 152 coverage - IMAGE to VIDEO/GIF transitions
  describe('Media Type Changes - Line 152 Coverage', () => {
    it('should clear image data when switching from IMAGE to VIDEO (Line 152 - Android)', () => {
      const propsWithImageContent = {
        ...defaultProps,
        androidContent: { ...defaultAndroidContent, mediaType: IMAGE },
      };

      mockSetAndroidContent.mockImplementation((updater) => {
        if (typeof updater === 'function') {
          updater(propsWithImageContent.androidContent);
        }
      });

      const { result } = renderHook(() => usePlatformSync(propsWithImageContent));

      act(() => {
        result.current.handleMediaTypeChange(ANDROID, VIDEO);
      });

      expect(mockUpdateOnMpushImageReUpload).toHaveBeenCalled();
      expect(mockUpdateOnMpushVideoReUpload).not.toHaveBeenCalled();
    });

    it('should clear image data when switching from IMAGE to GIF (Line 152 - Android)', () => {
      const propsWithImageContent = {
        ...defaultProps,
        androidContent: { ...defaultAndroidContent, mediaType: IMAGE },
      };

      mockSetAndroidContent.mockImplementation((updater) => {
        if (typeof updater === 'function') {
          updater(propsWithImageContent.androidContent);
        }
      });

      const { result } = renderHook(() => usePlatformSync(propsWithImageContent));

      act(() => {
        result.current.handleMediaTypeChange(ANDROID, GIF);
      });

      expect(mockUpdateOnMpushImageReUpload).toHaveBeenCalled();
      expect(mockUpdateOnMpushVideoReUpload).not.toHaveBeenCalled();
    });

    it('should clear image data when switching from IMAGE to VIDEO (Line 152 - iOS)', () => {
      const propsWithImageContent = {
        ...defaultProps,
        iosContent: { ...defaultIosContent, mediaType: IMAGE },
      };

      mockSetIosContent.mockImplementation((updater) => {
        if (typeof updater === 'function') {
          updater(propsWithImageContent.iosContent);
        }
      });

      const { result } = renderHook(() => usePlatformSync(propsWithImageContent));

      act(() => {
        result.current.handleMediaTypeChange(IOS, VIDEO);
      });

      expect(mockUpdateOnMpushImageReUpload).toHaveBeenCalled();
      expect(mockUpdateOnMpushVideoReUpload).not.toHaveBeenCalled();
    });

    it('should clear image data when switching from IMAGE to GIF (Line 152 - iOS)', () => {
      const propsWithImageContent = {
        ...defaultProps,
        iosContent: { ...defaultIosContent, mediaType: IMAGE },
      };

      mockSetIosContent.mockImplementation((updater) => {
        if (typeof updater === 'function') {
          updater(propsWithImageContent.iosContent);
        }
      });

      const { result } = renderHook(() => usePlatformSync(propsWithImageContent));

      act(() => {
        result.current.handleMediaTypeChange(IOS, GIF);
      });

      expect(mockUpdateOnMpushImageReUpload).toHaveBeenCalled();
      expect(mockUpdateOnMpushVideoReUpload).not.toHaveBeenCalled();
    });

    it('should clear image data when switching from IMAGE to VIDEO with sync enabled (Line 152)', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const propsWithImageContent = {
        ...syncProps,
        androidContent: { ...defaultAndroidContent, mediaType: IMAGE },
      };

      mockSetAndroidContent.mockImplementation((updater) => {
        if (typeof updater === 'function') {
          updater(propsWithImageContent.androidContent);
        }
      });

      const { result } = renderHook(() => usePlatformSync(propsWithImageContent));

      act(() => {
        result.current.handleMediaTypeChange(ANDROID, VIDEO);
      });

      expect(mockUpdateOnMpushImageReUpload).toHaveBeenCalled();
      expect(mockUpdateOnMpushVideoReUpload).not.toHaveBeenCalled();
      // Should also sync to iOS
      expect(mockSetIosContent).toHaveBeenCalledWith(expect.objectContaining({
        mediaType: VIDEO,
      }));
    });

    it('should clear image data when switching from IMAGE to GIF with sync enabled (Line 152)', () => {
      const syncProps = { ...defaultProps, sameContent: true };
      const propsWithImageContent = {
        ...syncProps,
        iosContent: { ...defaultIosContent, mediaType: IMAGE },
      };

      mockSetIosContent.mockImplementation((updater) => {
        if (typeof updater === 'function') {
          updater(propsWithImageContent.iosContent);
        }
      });

      const { result } = renderHook(() => usePlatformSync(propsWithImageContent));

      act(() => {
        result.current.handleMediaTypeChange(IOS, GIF);
      });

      expect(mockUpdateOnMpushImageReUpload).toHaveBeenCalled();
      expect(mockUpdateOnMpushVideoReUpload).not.toHaveBeenCalled();
      // Should also sync to Android
      expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.objectContaining({
        mediaType: GIF,
      }));
    });
  });

  // Debounce effect and deepSyncContent - covering lines 50-59, 90, 113
  it('should debounce and sync content between platforms', async () => {
    jest.useFakeTimers();
    const setAndroidContent = jest.fn();
    const setIosContent = jest.fn();
    const changeSourceRef = { current: 'android' };
    const hook = renderHook(() => usePlatformSync({
      setAndroidContent,
      setIosContent,
      validateTitle: jest.fn(),
      validateMessage: jest.fn(),
      setAndroidTitleError: jest.fn(),
      setAndroidMessageError: jest.fn(),
      setIosTitleError: jest.fn(),
      setIosMessageError: jest.fn(),
      androidContent: { title: 'A', message: 'B' },
      iosContent: { title: 'C', message: 'D' },
      updateOnMpushImageReUpload: jest.fn(),
      updateOnMpushVideoReUpload: jest.fn(),
      sameContent: true,
      changeSourceRef,
    }));
    // Simulate content change
    hook.rerender();
    jest.advanceTimersByTime(600);
    expect(setIosContent).toHaveBeenCalledWith({ title: 'A', message: 'B' });
    jest.useRealTimers();
  });

  it('should use deepSyncContent to sync buttons with platform property', () => {
    const setAndroidContent = jest.fn();
    const setIosContent = jest.fn();
    const changeSourceRef = { current: null };

    const { result } = renderHook(() => usePlatformSync({
      setAndroidContent,
      setIosContent,
      validateTitle: jest.fn(),
      validateMessage: jest.fn(),
      setAndroidTitleError: jest.fn(),
      setAndroidMessageError: jest.fn(),
      setIosTitleError: jest.fn(),
      setIosMessageError: jest.fn(),
      androidContent: { title: 'A' },
      iosContent: { title: 'B' },
      updateOnMpushImageReUpload: jest.fn(),
      updateOnMpushVideoReUpload: jest.fn(),
      sameContent: true,
      changeSourceRef,
    }));

    // Test the deepSyncContent functionality by calling handleButtonChange
    act(() => {
      result.current.handleButtonChange('ANDROID', [{ text: 'btn' }]);
    });

    // Verify that the buttons were synced with platform property
    expect(setIosContent).toHaveBeenCalledWith(
      expect.objectContaining({
        buttons: expect.arrayContaining([
          expect.objectContaining({
            text: 'btn',
            platform: 'IOS',
          }),
        ]),
      }),
    );
  });

  it('should handle handleTitleChange with sameContent true', () => {
    const setAndroidContent = jest.fn();
    const setIosContent = jest.fn();
    const setAndroidTitleError = jest.fn();
    const setIosTitleError = jest.fn();
    const validateTitle = jest.fn();
    const changeSourceRef = { current: null };
    const hook = renderHook(() => usePlatformSync({
      setAndroidContent,
      setIosContent,
      validateTitle,
      validateMessage: jest.fn(),
      setAndroidTitleError,
      setAndroidMessageError: jest.fn(),
      setIosTitleError,
      setIosMessageError: jest.fn(),
      androidContent: { title: 'A' },
      iosContent: { title: 'B' },
      updateOnMpushImageReUpload: jest.fn(),
      updateOnMpushVideoReUpload: jest.fn(),
      sameContent: true,
      changeSourceRef,
    }));
    act(() => {
      hook.result.current.handleTitleChange('ANDROID', 'New Title');
    });
    expect(setAndroidContent).toHaveBeenCalled();
    expect(setIosContent).toHaveBeenCalled();
    expect(setAndroidTitleError).toHaveBeenCalled();
    expect(setIosTitleError).toHaveBeenCalled();
  });

  it('should handle handleMessageChange with sameContent true', () => {
    const setAndroidContent = jest.fn();
    const setIosContent = jest.fn();
    const setAndroidMessageError = jest.fn();
    const setIosMessageError = jest.fn();
    const validateMessage = jest.fn();
    const changeSourceRef = { current: null };
    const hook = renderHook(() => usePlatformSync({
      setAndroidContent,
      setIosContent,
      validateTitle: jest.fn(),
      validateMessage,
      setAndroidTitleError: jest.fn(),
      setAndroidMessageError,
      setIosTitleError: jest.fn(),
      setIosMessageError,
      androidContent: { message: 'A' },
      iosContent: { message: 'B' },
      updateOnMpushImageReUpload: jest.fn(),
      updateOnMpushVideoReUpload: jest.fn(),
      sameContent: true,
      changeSourceRef,
    }));
    act(() => {
      hook.result.current.handleMessageChange('ANDROID', 'New Message');
    });
    expect(setAndroidContent).toHaveBeenCalled();
    expect(setIosContent).toHaveBeenCalled();
    expect(setAndroidMessageError).toHaveBeenCalled();
    expect(setIosMessageError).toHaveBeenCalled();
  });

  it('should handle handleMediaTypeChange with sameContent true and previousMediaType !== value', () => {
    const setAndroidContent = jest.fn();
    const setIosContent = jest.fn();
    const updateOnMpushImageReUpload = jest.fn();
    const updateOnMpushVideoReUpload = jest.fn();
    const hook = renderHook(() => usePlatformSync({
      setAndroidContent,
      setIosContent,
      validateTitle: jest.fn(),
      validateMessage: jest.fn(),
      setAndroidTitleError: jest.fn(),
      setAndroidMessageError: jest.fn(),
      setIosTitleError: jest.fn(),
      setIosMessageError: jest.fn(),
      androidContent: { mediaType: 'IMAGE' },
      iosContent: { mediaType: 'VIDEO' },
      updateOnMpushImageReUpload,
      updateOnMpushVideoReUpload,
      sameContent: true,
      changeSourceRef: { current: null },
    }));
    act(() => {
      hook.result.current.handleMediaTypeChange('ANDROID', 'VIDEO');
    });
    expect(setAndroidContent).toHaveBeenCalled();
    expect(setIosContent).toHaveBeenCalled();
    // Should call updateOnMpushImageReUpload since previousMediaType was IMAGE and value is VIDEO
    expect(updateOnMpushImageReUpload).toHaveBeenCalled();
  });
});
