/**
 * Tests for Templates container - WEBPUSH channel additions
 *
 * Covers:
 * - extractTemplateContentForPreview for WEBPUSH channel
 * - isTestAndPreviewSupported with WEBPUSH channel
 */

import React from 'react';
import { shallowWithIntl } from '../../../helpers/intl-enzym-test-helpers';
import { Templates } from '../index';

jest.mock('../../CreativesContainer', () => ({
  __esModule: true,
  default: (props) => (
    <div className="creatives-container-mock" {...props}>
      CreativesContainer
    </div>
  ),
}));

// Helper: build a valid template for WEBPUSH
// extractTemplateContentForPreview reads:
//   - template.versions.base.content.webpush  → webpushContent
//   - template.definition.accountId           → accountId
//   - template.name                            → templateName
const makeTemplate = (webpush = {}, extra = {}) => ({
  name: 'My Template',
  definition: { accountId: 'acc-123' },
  versions: {
    base: {
      content: { webpush },
    },
  },
  ...extra,
});

describe('Templates - WEBPUSH channel', () => {
  const mockActions = {
    getWeCrmAccounts: jest.fn(),
    setChannelAccount: jest.fn(),
    getAllTemplates: jest.fn(),
    getUserList: jest.fn(),
    getSenderDetails: jest.fn(),
    resetTemplate: jest.fn(),
    setArchivedMode: jest.fn(),
    clearTemplateSelection: jest.fn(),
    toggleTemplateSelection: jest.fn(),
  };

  const baseProps = {
    route: { name: 'webpush' },
    Templates: { templates: [] },
    actions: mockActions,
    location: { pathname: '/webpush', query: {}, search: '' },
    EmailCreate: { duplicateTemplateInProgress: false },
    isFullMode: false,
    intl: { formatMessage: jest.fn((msg) => msg.defaultMessage || '') },
  };

  beforeEach(() => {
    jest.clearAllMocks();
  });

  const renderComponent = (channel = 'webpush') => {
    const props = { ...baseProps, route: { name: channel } };
    return shallowWithIntl(<Templates {...props} />);
  };

  // ─────────────────────────────────────────────────────────────────────────
  describe('isTestAndPreviewSupported', () => {
    it('should return true for WEBPUSH channel', () => {
      const component = renderComponent('webpush');
      component.setState({ channel: 'webpush' });
      expect(component.instance().isTestAndPreviewSupported()).toBe(true);
    });

    it('should return true for WEBPUSH in uppercase state', () => {
      const component = renderComponent('webpush');
      component.setState({ channel: 'WEBPUSH' });
      expect(component.instance().isTestAndPreviewSupported()).toBe(true);
    });

    it('should return true for EMAIL channel', () => {
      const component = renderComponent('webpush');
      component.setState({ channel: 'email' });
      expect(component.instance().isTestAndPreviewSupported()).toBe(true);
    });

    it('should return true for SMS channel', () => {
      const component = renderComponent('webpush');
      component.setState({ channel: 'sms' });
      expect(component.instance().isTestAndPreviewSupported()).toBe(true);
    });

    it('should return true for INAPP channel', () => {
      const component = renderComponent('webpush');
      component.setState({ channel: 'inapp' });
      expect(component.instance().isTestAndPreviewSupported()).toBe(true);
    });

    it('should return true for VIBER channel', () => {
      const component = renderComponent('webpush');
      component.setState({ channel: 'viber' });
      expect(component.instance().isTestAndPreviewSupported()).toBe(true);
    });

    it('should return true for ZALO channel', () => {
      const component = renderComponent('webpush');
      component.setState({ channel: 'zalo' });
      expect(component.instance().isTestAndPreviewSupported()).toBe(true);
    });

    it('should return false for WHATSAPP channel', () => {
      const component = renderComponent('webpush');
      component.setState({ channel: 'whatsapp' });
      expect(component.instance().isTestAndPreviewSupported()).toBe(false);
    });

    it('should return false for RCS channel', () => {
      const component = renderComponent('webpush');
      component.setState({ channel: 'rcs' });
      expect(component.instance().isTestAndPreviewSupported()).toBe(false);
    });
  });

  // ─────────────────────────────────────────────────────────────────────────
  describe('extractTemplateContentForPreview - WEBPUSH channel', () => {
    it('should return null when template has no versions.base', () => {
      const consoleSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
      const component = renderComponent('webpush');
      const result = component.instance().extractTemplateContentForPreview(
        { name: 'T', definition: {} },
        'WEBPUSH'
      );
      expect(result).toBeNull();
      consoleSpy.mockRestore();
    });

    it('should extract title and message from versions.base.content.webpush', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({ title: 'Push Title', message: 'Push body' });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result).toBeDefined();
      expect(result.channel).toBe('WEBPUSH');
      expect(result.accountId).toBe('acc-123');
      expect(result.content.title).toBe('Push Title');
      expect(result.content.message).toBe('Push body');
      expect(result.messageSubject).toBe('My Template');
      expect(result.offers).toEqual([]);
    });

    it('should fall back to title for messageSubject when template name is empty', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({ title: 'Title Only', message: 'M' }, { name: '' });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.messageSubject).toBe('Title Only');
    });

    it('should extract brandIcon as iconImageUrl', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({
        title: 'T',
        message: 'M',
        brandIcon: 'https://example.com/brand.png',
      });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.iconImageUrl).toBe('https://example.com/brand.png');
    });

    it('should use iconImageUrl field when brandIcon is absent', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({
        title: 'T',
        message: 'M',
        iconImageUrl: 'https://example.com/icon.png',
      });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.iconImageUrl).toBe('https://example.com/icon.png');
    });

    it('should NOT include iconImageUrl when neither brandIcon nor iconImageUrl present', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({ title: 'T', message: 'M' });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.iconImageUrl).toBeUndefined();
    });

    it('should convert onClickAction type URL to EXTERNAL_URL cta', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({
        title: 'T',
        message: 'M',
        onClickAction: { type: 'URL', url: 'https://example.com' },
      });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.cta).toEqual({ type: 'EXTERNAL_URL', actionLink: 'https://example.com' });
    });

    it('should preserve onClickAction type SITE_URL as-is', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({
        title: 'T',
        message: 'M',
        onClickAction: { type: 'SITE_URL', url: 'https://site.com' },
      });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.cta).toEqual({ type: 'SITE_URL', actionLink: 'https://site.com' });
    });

    it('should use existingCta when onClickAction is absent', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({
        title: 'T',
        message: 'M',
        cta: { type: 'EXTERNAL_URL', actionLink: 'https://existing.com' },
      });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.cta).toEqual({ type: 'EXTERNAL_URL', actionLink: 'https://existing.com' });
    });

    it('should default existingCta type to EXTERNAL_URL when type is missing', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({
        title: 'T',
        message: 'M',
        cta: { actionLink: 'https://example.com' },
      });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.cta.type).toBe('EXTERNAL_URL');
    });

    it('should NOT include cta when neither onClickAction nor cta present', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({ title: 'T', message: 'M' });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.cta).toBeUndefined();
    });

    it('should build expandableDetails from image and ctas', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({
        title: 'T',
        message: 'M',
        image: 'https://example.com/image.jpg',
        ctas: [{ type: 'URL', actionText: 'Click', actionLink: 'https://a.com', action: '' }],
      });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.expandableDetails).toBeDefined();
      expect(result.content.expandableDetails.media).toEqual([
        { url: 'https://example.com/image.jpg', type: 'IMAGE' },
      ]);
      expect(result.content.expandableDetails.ctas[0].title).toBe('Click');
      expect(result.content.expandableDetails.ctas[0].type).toBe('EXTERNAL_URL');
    });

    it('should convert CTA type URL → EXTERNAL_URL in expandableDetails.ctas', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({
        title: 'T',
        message: 'M',
        ctas: [{ type: 'URL', actionText: 'Go', actionLink: 'https://x.com' }],
      });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.expandableDetails.ctas[0].type).toBe('EXTERNAL_URL');
    });

    it('should keep EXTERNAL_URL type unchanged in expandableDetails.ctas', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({
        title: 'T',
        message: 'M',
        ctas: [{ type: 'EXTERNAL_URL', title: 'Go', actionLink: 'https://x.com' }],
      });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.expandableDetails.ctas[0].type).toBe('EXTERNAL_URL');
    });

    it('should build image-only expandableDetails when no ctas', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({
        title: 'T',
        message: 'M',
        image: 'https://example.com/img.jpg',
      });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.expandableDetails.media).toHaveLength(1);
      expect(result.content.expandableDetails.ctas).toEqual([]);
    });

    it('should build ctas-only expandableDetails when no image', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({
        title: 'T',
        message: 'M',
        ctas: [{ type: 'EXTERNAL_URL', actionText: 'Btn', actionLink: 'https://b.com' }],
      });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.expandableDetails.media).toEqual([]);
      expect(result.content.expandableDetails.ctas).toHaveLength(1);
    });

    it('should use existingExpandable when no image and no ctas', () => {
      const component = renderComponent('webpush');
      const existingExpandable = {
        media: [{ url: 'https://example.com/existing.jpg', type: 'IMAGE' }],
        ctas: [{ title: 'Existing', actionLink: 'https://existing.com', type: 'EXTERNAL_URL' }],
      };
      const template = makeTemplate({
        title: 'T',
        message: 'M',
        expandableDetails: existingExpandable,
      });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.expandableDetails).toEqual(existingExpandable);
    });

    it('should NOT include expandableDetails when none present', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({ title: 'T', message: 'M' });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result.content.expandableDetails).toBeUndefined();
    });

    it('should handle empty webpush content gracefully', () => {
      const component = renderComponent('webpush');
      const template = makeTemplate({}, { name: '' });

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result).toBeDefined();
      expect(result.content.title).toBe('');
      expect(result.content.message).toBe('');
    });

    it('should handle missing definition.accountId gracefully (returns null)', () => {
      const component = renderComponent('webpush');
      const template = {
        name: 'T',
        versions: { base: { content: { webpush: { title: 'T', message: 'M' } } } },
        // no definition
      };

      const result = component.instance().extractTemplateContentForPreview(template, 'WEBPUSH');
      expect(result).toBeDefined();
      expect(result.accountId).toBeNull();
    });

    it('should return null for unsupported channel', () => {
      const consoleSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
      const component = renderComponent('webpush');
      const template = makeTemplate({ title: 'T', message: 'M' });

      const result = component.instance().extractTemplateContentForPreview(template, 'UNSUPPORTED_CHANNEL');
      expect(result).toBeNull();
      consoleSpy.mockRestore();
    });
  });
});
