/**
 * Unit tests for getTemplateContent logic used in WebPushCreate
 *
 * The getTemplateContent function (useCallback) transforms component state
 * into a structured content object for TestAndPreviewSlidebox.
 * Tested here as a pure function matching the exact implementation logic.
 */

import {
  WEBPUSH_MEDIA_TYPES,
  BRAND_ICON_OPTIONS,
  ON_CLICK_BEHAVIOUR_OPTIONS,
} from '../../constants';

/**
 * Mirrors the getTemplateContent useCallback in WebPushCreate/index.js.
 * Keep in sync if the source function changes.
 */
const getTemplateContent = ({
  notificationTitle = '',
  message = '',
  accountId = null,
  mediaType = WEBPUSH_MEDIA_TYPES.NONE,
  imageSrc = '',
  brandIconOption = BRAND_ICON_OPTIONS.DONT_SHOW,
  brandIconSrc = '',
  buttons = [],
  onClickBehaviour = ON_CLICK_BEHAVIOUR_OPTIONS.SITE_URL,
  redirectUrl = '',
  websiteLink = '',
  templateName = '',
} = {}) => {
  let cta = null;
  if (onClickBehaviour === ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL && redirectUrl) {
    cta = { type: 'EXTERNAL_URL', actionLink: redirectUrl?.trim() };
  } else if (onClickBehaviour === ON_CLICK_BEHAVIOUR_OPTIONS.SITE_URL && websiteLink) {
    cta = { type: 'SITE_URL', actionLink: websiteLink };
  }

  const hasImage = mediaType === WEBPUSH_MEDIA_TYPES.IMAGE && imageSrc;
  const hasCtas = buttons?.length > 0;
  let expandableDetails = null;
  if (hasImage || hasCtas) {
    expandableDetails = {
      media: hasImage ? [{ url: imageSrc, type: 'IMAGE' }] : [],
      ctas: hasCtas
        ? buttons.map((btn) => ({
            type: 'EXTERNAL_URL',
            action: '',
            title: btn.text || '',
            actionLink: btn.url || '',
          }))
        : [],
    };
  }

  const iconImageUrl =
    brandIconOption !== BRAND_ICON_OPTIONS.DONT_SHOW && brandIconSrc ? brandIconSrc : undefined;

  return {
    channel: 'WEBPUSH',
    accountId,
    content: {
      title: notificationTitle || '',
      message: message || '',
      ...(iconImageUrl ? { iconImageUrl } : {}),
      ...(cta ? { cta } : {}),
      ...(expandableDetails ? { expandableDetails } : {}),
    },
    messageSubject: templateName || notificationTitle || '',
    offers: [],
  };
};

describe('getTemplateContent (WebPushCreate)', () => {
  describe('Basic structure', () => {
    it('should return channel WEBPUSH', () => {
      const result = getTemplateContent({ notificationTitle: 'T', message: 'M' });
      expect(result.channel).toBe('WEBPUSH');
    });

    it('should include accountId', () => {
      const result = getTemplateContent({ accountId: 'acc-123' });
      expect(result.accountId).toBe('acc-123');
    });

    it('should return null accountId when not provided', () => {
      const result = getTemplateContent({});
      expect(result.accountId).toBeNull();
    });

    it('should include title in content', () => {
      const result = getTemplateContent({ notificationTitle: 'Hello World' });
      expect(result.content.title).toBe('Hello World');
    });

    it('should include message in content', () => {
      const result = getTemplateContent({ message: 'Body text' });
      expect(result.content.message).toBe('Body text');
    });

    it('should default title to empty string', () => {
      const result = getTemplateContent({});
      expect(result.content.title).toBe('');
    });

    it('should default message to empty string', () => {
      const result = getTemplateContent({});
      expect(result.content.message).toBe('');
    });

    it('should include offers as empty array', () => {
      const result = getTemplateContent({});
      expect(result.offers).toEqual([]);
    });
  });

  describe('messageSubject', () => {
    it('should use templateName as messageSubject', () => {
      const result = getTemplateContent({ templateName: 'My Template', notificationTitle: 'T' });
      expect(result.messageSubject).toBe('My Template');
    });

    it('should fall back to notificationTitle when templateName is empty', () => {
      const result = getTemplateContent({ templateName: '', notificationTitle: 'Push Title' });
      expect(result.messageSubject).toBe('Push Title');
    });

    it('should be empty string when both templateName and notificationTitle are empty', () => {
      const result = getTemplateContent({ templateName: '', notificationTitle: '' });
      expect(result.messageSubject).toBe('');
    });
  });

  describe('CTA - REDIRECT_TO_URL', () => {
    it('should set EXTERNAL_URL cta when behaviour is REDIRECT_TO_URL with url', () => {
      const result = getTemplateContent({
        onClickBehaviour: ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL,
        redirectUrl: 'https://redirect.com',
      });
      expect(result.content.cta).toEqual({ type: 'EXTERNAL_URL', actionLink: 'https://redirect.com' });
    });

    it('should trim redirectUrl whitespace', () => {
      const result = getTemplateContent({
        onClickBehaviour: ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL,
        redirectUrl: '  https://redirect.com  ',
      });
      expect(result.content.cta.actionLink).toBe('https://redirect.com');
    });

    it('should NOT set cta when REDIRECT_TO_URL but redirectUrl is empty', () => {
      const result = getTemplateContent({
        onClickBehaviour: ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL,
        redirectUrl: '',
      });
      expect(result.content.cta).toBeUndefined();
    });
  });

  describe('CTA - SITE_URL', () => {
    it('should set SITE_URL cta when behaviour is SITE_URL with websiteLink', () => {
      const result = getTemplateContent({
        onClickBehaviour: ON_CLICK_BEHAVIOUR_OPTIONS.SITE_URL,
        websiteLink: 'https://mysite.com',
      });
      expect(result.content.cta).toEqual({ type: 'SITE_URL', actionLink: 'https://mysite.com' });
    });

    it('should NOT set cta when SITE_URL but websiteLink is empty', () => {
      const result = getTemplateContent({
        onClickBehaviour: ON_CLICK_BEHAVIOUR_OPTIONS.SITE_URL,
        websiteLink: '',
      });
      expect(result.content.cta).toBeUndefined();
    });

    it('should NOT include cta key at all when no url configured', () => {
      const result = getTemplateContent({
        onClickBehaviour: ON_CLICK_BEHAVIOUR_OPTIONS.SITE_URL,
        websiteLink: '',
        redirectUrl: '',
      });
      expect(Object.keys(result.content)).not.toContain('cta');
    });
  });

  describe('expandableDetails - image', () => {
    it('should include image media when mediaType is IMAGE and imageSrc is set', () => {
      const result = getTemplateContent({
        mediaType: WEBPUSH_MEDIA_TYPES.IMAGE,
        imageSrc: 'https://example.com/img.jpg',
      });
      expect(result.content.expandableDetails).toBeDefined();
      expect(result.content.expandableDetails.media).toEqual([
        { url: 'https://example.com/img.jpg', type: 'IMAGE' },
      ]);
    });

    it('should NOT include expandableDetails when mediaType is NONE', () => {
      const result = getTemplateContent({
        mediaType: WEBPUSH_MEDIA_TYPES.NONE,
        imageSrc: 'https://example.com/img.jpg',
      });
      expect(result.content.expandableDetails).toBeUndefined();
    });

    it('should NOT include expandableDetails when imageSrc is empty even if mediaType is IMAGE', () => {
      const result = getTemplateContent({
        mediaType: WEBPUSH_MEDIA_TYPES.IMAGE,
        imageSrc: '',
        buttons: [],
      });
      expect(result.content.expandableDetails).toBeUndefined();
    });
  });

  describe('expandableDetails - buttons', () => {
    it('should include ctas when buttons are provided', () => {
      const result = getTemplateContent({
        buttons: [{ text: 'Click Me', url: 'https://click.com' }],
      });
      expect(result.content.expandableDetails).toBeDefined();
      expect(result.content.expandableDetails.ctas).toEqual([
        { type: 'EXTERNAL_URL', action: '', title: 'Click Me', actionLink: 'https://click.com' },
      ]);
    });

    it('should map multiple buttons to ctas', () => {
      const result = getTemplateContent({
        buttons: [
          { text: 'Btn1', url: 'https://a.com' },
          { text: 'Btn2', url: 'https://b.com' },
        ],
      });
      expect(result.content.expandableDetails.ctas).toHaveLength(2);
    });

    it('should handle button with empty text and url', () => {
      const result = getTemplateContent({
        buttons: [{ text: '', url: '' }],
      });
      expect(result.content.expandableDetails.ctas[0]).toEqual({
        type: 'EXTERNAL_URL',
        action: '',
        title: '',
        actionLink: '',
      });
    });

    it('should NOT include expandableDetails when buttons array is empty', () => {
      const result = getTemplateContent({ buttons: [] });
      expect(result.content.expandableDetails).toBeUndefined();
    });

    it('should NOT include expandableDetails when buttons is null', () => {
      const result = getTemplateContent({ buttons: null });
      expect(result.content.expandableDetails).toBeUndefined();
    });

    it('should NOT include expandableDetails when buttons is undefined', () => {
      const result = getTemplateContent({ buttons: undefined });
      expect(result.content.expandableDetails).toBeUndefined();
    });
  });

  describe('expandableDetails - image + buttons combined', () => {
    it('should include both media and ctas when image and buttons present', () => {
      const result = getTemplateContent({
        mediaType: WEBPUSH_MEDIA_TYPES.IMAGE,
        imageSrc: 'https://img.com/a.jpg',
        buttons: [{ text: 'Go', url: 'https://go.com' }],
      });
      expect(result.content.expandableDetails.media).toHaveLength(1);
      expect(result.content.expandableDetails.ctas).toHaveLength(1);
    });
  });

  describe('brandIcon (iconImageUrl)', () => {
    it('should include iconImageUrl when brandIconOption is not DONT_SHOW and brandIconSrc is set', () => {
      const result = getTemplateContent({
        brandIconOption: BRAND_ICON_OPTIONS.UPLOAD_IMAGE,
        brandIconSrc: 'https://example.com/brand.png',
      });
      expect(result.content.iconImageUrl).toBe('https://example.com/brand.png');
    });

    it('should NOT include iconImageUrl when brandIconOption is DONT_SHOW', () => {
      const result = getTemplateContent({
        brandIconOption: BRAND_ICON_OPTIONS.DONT_SHOW,
        brandIconSrc: 'https://example.com/brand.png',
      });
      expect(result.content.iconImageUrl).toBeUndefined();
    });

    it('should NOT include iconImageUrl when brandIconSrc is empty', () => {
      const result = getTemplateContent({
        brandIconOption: BRAND_ICON_OPTIONS.UPLOAD_IMAGE,
        brandIconSrc: '',
      });
      expect(result.content.iconImageUrl).toBeUndefined();
    });

    it('should NOT include iconImageUrl key when not applicable', () => {
      const result = getTemplateContent({
        brandIconOption: BRAND_ICON_OPTIONS.DONT_SHOW,
        brandIconSrc: '',
      });
      expect(Object.keys(result.content)).not.toContain('iconImageUrl');
    });
  });

  describe('Full payload with all fields', () => {
    it('should build complete payload with title, message, cta, expandableDetails, iconImageUrl', () => {
      const result = getTemplateContent({
        notificationTitle: 'Full Title',
        message: 'Full body',
        accountId: 'acc-full',
        templateName: 'Full Template',
        mediaType: WEBPUSH_MEDIA_TYPES.IMAGE,
        imageSrc: 'https://img.com/full.jpg',
        brandIconOption: BRAND_ICON_OPTIONS.UPLOAD_IMAGE,
        brandIconSrc: 'https://icon.com/full.png',
        buttons: [{ text: 'Action', url: 'https://action.com' }],
        onClickBehaviour: ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL,
        redirectUrl: 'https://redirect.com',
        websiteLink: '',
      });

      expect(result).toEqual({
        channel: 'WEBPUSH',
        accountId: 'acc-full',
        content: {
          title: 'Full Title',
          message: 'Full body',
          iconImageUrl: 'https://icon.com/full.png',
          cta: { type: 'EXTERNAL_URL', actionLink: 'https://redirect.com' },
          expandableDetails: {
            media: [{ url: 'https://img.com/full.jpg', type: 'IMAGE' }],
            ctas: [{ type: 'EXTERNAL_URL', action: '', title: 'Action', actionLink: 'https://action.com' }],
          },
        },
        messageSubject: 'Full Template',
        offers: [],
      });
    });
  });
});
