import { createWebPushPayload } from './payloadBuilder';
import {
  WEBPUSH,
  WEBPUSH_MEDIA_TYPES,
  IMAGE_UPLOAD_METHODS,
  BRAND_ICON_OPTIONS,
  ON_CLICK_BEHAVIOUR_OPTIONS,
  ACTION_TYPES,
} from '../../constants';

describe('createWebPushPayload', () => {
  const defaultParams = {
    templateName: 'Test Template',
    notificationTitle: 'Test Title',
    message: 'Test Message',
    mediaType: WEBPUSH_MEDIA_TYPES.NONE,
    accountId: 'account123',
    isFullMode: true,
    imageSrc: '',
    imageUrl: '',
    imageUploadMethod: IMAGE_UPLOAD_METHODS.UPLOAD_IMAGE,
    brandIconOption: BRAND_ICON_OPTIONS.DONT_SHOW,
    brandIconSrc: '',
    brandIconUrl: '',
    buttons: [],
    onClickBehaviour: ON_CLICK_BEHAVIOUR_OPTIONS.SITE_URL,
    redirectUrl: '',
    websiteLink: 'https://example.com',
  };

  describe('Basic Payload Structure', () => {
    it('should create basic payload with required fields', () => {
      const payload = createWebPushPayload(defaultParams);

      expect(payload).toEqual({
        name: 'Test Template',
        type: WEBPUSH,
        definition: {
          accountId: 'account123',
        },
        versions: {
          base: {
            content: {
              webpush: {
                title: 'Test Title',
                message: 'Test Message',
                onClickAction: {
                  type: ACTION_TYPES.SITE_URL,
                  url: 'https://example.com',
                },
              },
            },
          },
        },
      });
    });

    it('should use notification title as name when not in full mode', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        isFullMode: false,
        templateName: '',
      });

      expect(payload.name).toBe('Test Title');
    });

    it('should use notification title as name when template name is empty in full mode', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        templateName: '',
      });

      expect(payload.name).toBe('Test Title');
    });

    it('should trim template name', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        templateName: '  Test Template  ',
      });

      expect(payload.name).toBe('Test Template');
    });

    it('should trim notification title', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        notificationTitle: '  Test Title  ',
      });

      expect(payload.versions.base.content.webpush.title).toBe('Test Title');
    });

    it('should trim message', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        message: '  Test Message  ',
      });

      expect(payload.versions.base.content.webpush.message).toBe('Test Message');
    });
  });

  describe('Media Type Handling', () => {
    it('should include mediaType when not NONE', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        mediaType: WEBPUSH_MEDIA_TYPES.IMAGE,
      });

      expect(payload.versions.base.content.webpush.mediaType).toBe(WEBPUSH_MEDIA_TYPES.IMAGE);
    });

    it('should not include mediaType when NONE', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        mediaType: WEBPUSH_MEDIA_TYPES.NONE,
      });

      expect(payload.versions.base.content.webpush.mediaType).toBeUndefined();
    });
  });

  describe('Image Handling', () => {
    it('should include image when mediaType is IMAGE and upload method is UPLOAD_IMAGE', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        mediaType: WEBPUSH_MEDIA_TYPES.IMAGE,
        imageUploadMethod: IMAGE_UPLOAD_METHODS.UPLOAD_IMAGE,
        imageSrc: 'secure/path/to/image.jpg',
      });

      expect(payload.versions.base.content.webpush.image).toBe('secure/path/to/image.jpg');
    });

    it('should include image when mediaType is IMAGE and upload method is ADD_IMAGE_URL', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        mediaType: WEBPUSH_MEDIA_TYPES.IMAGE,
        imageUploadMethod: IMAGE_UPLOAD_METHODS.ADD_IMAGE_URL,
        imageSrc: 'secure/path/to/image.jpg',
      });

      expect(payload.versions.base.content.webpush.image).toBe('secure/path/to/image.jpg');
    });

    it('should not include image when imageSrc is empty', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        mediaType: WEBPUSH_MEDIA_TYPES.IMAGE,
        imageUploadMethod: IMAGE_UPLOAD_METHODS.UPLOAD_IMAGE,
        imageSrc: '',
      });

      expect(payload.versions.base.content.webpush.image).toBeUndefined();
    });

    it('should not include image when mediaType is NONE', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        mediaType: WEBPUSH_MEDIA_TYPES.NONE,
        imageSrc: 'secure/path/to/image.jpg',
      });

      expect(payload.versions.base.content.webpush.image).toBeUndefined();
    });
  });

  describe('Brand Icon Handling', () => {
    it('should include brandIcon when option is UPLOAD_IMAGE', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        brandIconOption: BRAND_ICON_OPTIONS.UPLOAD_IMAGE,
        brandIconSrc: 'secure/path/to/brand-icon.jpg',
      });

      expect(payload.versions.base.content.webpush.brandIcon).toBe('secure/path/to/brand-icon.jpg');
    });

    it('should not include brandIcon when option is DONT_SHOW', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        brandIconOption: BRAND_ICON_OPTIONS.DONT_SHOW,
        brandIconSrc: 'secure/path/to/brand-icon.jpg',
      });

      expect(payload.versions.base.content.webpush.brandIcon).toBeUndefined();
    });

    it('should not include brandIcon when brandIconSrc is empty', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        brandIconOption: BRAND_ICON_OPTIONS.UPLOAD_IMAGE,
        brandIconSrc: '',
      });

      expect(payload.versions.base.content.webpush.brandIcon).toBeUndefined();
    });
  });

  describe('On-Click Behaviour', () => {
    it('should include onClickAction with URL type when REDIRECT_TO_URL is selected', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        onClickBehaviour: ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL,
        redirectUrl: 'https://example.com',
      });

      expect(payload.versions.base.content.webpush.onClickAction).toEqual({
        type: ACTION_TYPES.URL,
        url: 'https://example.com',
      });
    });

    it('should trim redirectUrl', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        onClickBehaviour: ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL,
        redirectUrl: '  https://example.com  ',
      });

      expect(payload.versions.base.content.webpush.onClickAction.url).toBe('https://example.com');
    });

    it('should include onClickAction with SITE_URL type when SITE_URL is selected', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        onClickBehaviour: ON_CLICK_BEHAVIOUR_OPTIONS.SITE_URL,
        websiteLink: 'https://example.com',
      });

      expect(payload.versions.base.content.webpush.onClickAction).toEqual({
        type: ACTION_TYPES.SITE_URL,
        url: 'https://example.com',
      });
    });

    it('should not include onClickAction when redirectUrl is empty and REDIRECT_TO_URL is selected', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        onClickBehaviour: ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL,
        redirectUrl: '',
      });

      // When redirectUrl is empty, onClickAction should not be included
      expect(payload.versions.base.content.webpush.onClickAction).toBeUndefined();
    });
  });

  describe('CTA Buttons', () => {
    it('should include ctas when buttons array has items', () => {
      const buttons = [
        { text: 'Button 1', url: 'https://example.com/1', type: 'primary' },
        { text: 'Button 2', url: 'https://example.com/2', type: 'secondary' },
      ];

      const payload = createWebPushPayload({
        ...defaultParams,
        buttons,
      });

      expect(payload.versions.base.content.webpush.ctas).toEqual([
        {
          actionText: 'Button 1',
          type: ACTION_TYPES.URL,
          actionLink: 'https://example.com/1',
        },
        {
          actionText: 'Button 2',
          type: ACTION_TYPES.URL,
          actionLink: 'https://example.com/2',
        },
      ]);
    });

    it('should not include ctas when buttons array is empty', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        buttons: [],
      });

      expect(payload.versions.base.content.webpush.ctas).toBeUndefined();
    });

    it('should not include ctas when buttons is null', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        buttons: null,
      });

      expect(payload.versions.base.content.webpush.ctas).toBeUndefined();
    });

    it('should not include ctas when buttons is undefined', () => {
      const payload = createWebPushPayload({
        ...defaultParams,
        buttons: undefined,
      });

      expect(payload.versions.base.content.webpush.ctas).toBeUndefined();
    });
  });

  describe('Combined Scenarios', () => {
    it('should create complete payload with all features', () => {
      const buttons = [
        { text: 'Click Me', url: 'https://example.com', type: 'primary' },
      ];

      const payload = createWebPushPayload({
        templateName: 'Complete Template',
        notificationTitle: 'Complete Title',
        message: 'Complete Message',
        mediaType: WEBPUSH_MEDIA_TYPES.IMAGE,
        accountId: 'account123',
        isFullMode: true,
        imageSrc: 'secure/path/to/image.jpg',
        imageUrl: 'https://example.com/image.jpg',
        imageUploadMethod: IMAGE_UPLOAD_METHODS.UPLOAD_IMAGE,
        brandIconOption: BRAND_ICON_OPTIONS.UPLOAD_IMAGE,
        brandIconSrc: 'secure/path/to/brand-icon.jpg',
        brandIconUrl: '',
        buttons,
        onClickBehaviour: ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL,
        redirectUrl: 'https://example.com/redirect',
      });

      expect(payload).toEqual({
        name: 'Complete Template',
        type: WEBPUSH,
        definition: {
          accountId: 'account123',
        },
        versions: {
          base: {
            content: {
              webpush: {
                title: 'Complete Title',
                message: 'Complete Message',
                mediaType: WEBPUSH_MEDIA_TYPES.IMAGE,
                image: 'secure/path/to/image.jpg',
                brandIcon: 'secure/path/to/brand-icon.jpg',
                onClickAction: {
                  type: ACTION_TYPES.URL,
                  url: 'https://example.com/redirect',
                },
                ctas: [
                  {
                    actionText: 'Click Me',
                    type: ACTION_TYPES.URL,
                    actionLink: 'https://example.com',
                  },
                ],
              },
            },
          },
        },
      });
    });

    it('should handle empty strings and null values gracefully', () => {
      const payload = createWebPushPayload({
        templateName: '',
        notificationTitle: '',
        message: '',
        mediaType: WEBPUSH_MEDIA_TYPES.NONE,
        accountId: 'account123',
        isFullMode: false,
        imageSrc: '',
        imageUrl: '',
        imageUploadMethod: IMAGE_UPLOAD_METHODS.UPLOAD_IMAGE,
        brandIconOption: BRAND_ICON_OPTIONS.DONT_SHOW,
        brandIconSrc: '',
        brandIconUrl: '',
        buttons: [],
        onClickBehaviour: ON_CLICK_BEHAVIOUR_OPTIONS.SITE_URL,
        redirectUrl: '',
        websiteLink: 'https://example.com',
      });

      expect(payload.name).toBe('');
      expect(payload.versions.base.content.webpush.title).toBe('');
      expect(payload.versions.base.content.webpush.message).toBe('');
      expect(payload.versions.base.content.webpush.mediaType).toBeUndefined();
      expect(payload.versions.base.content.webpush.image).toBeUndefined();
      expect(payload.versions.base.content.webpush.brandIcon).toBeUndefined();
      expect(payload.versions.base.content.webpush.onClickAction).toEqual({
        type: ACTION_TYPES.SITE_URL,
        url: 'https://example.com',
      });
      expect(payload.versions.base.content.webpush.ctas).toBeUndefined();
    });
  });
});

