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

import { Creatives } from '../index';
import mockdata from '../../mockdata';

const {
  whatsappTemplates,
  whatsappGetCreativeData1,
  whatsappGetCreativeData2,
  whatsappGetTemplateData1,
  whatsappGetTemplateData2,
  rcsTemplates,
  rcsEditTemplateData,
  smsEditTemplateData,
  smsTemplates,
  emailEditTemplateData,
  emailTemplates,
  loyaltyMetaData,
} = mockdata;

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

describe('Test SlideBoxContent container', () => {
  const handleCloseCreatives = jest.fn();
  const getCreativesData = jest.fn();
  const getCdnTransformationConfig = jest.fn();
  const getLiquidTags = jest.fn();
  let renderedComponent;

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

  const renderFunction = (channel, mode, templates, templateData) => {
    renderedComponent = shallowWithIntl(
      <Creatives
        loyaltyMetaData={loyaltyMetaData}
        Templates={templates}
        channel={channel}
        slidBoxContent={mode}
        templateData={templateData}
        handleCloseCreatives={handleCloseCreatives}
        getCreativesData={getCreativesData}
        templateActions={{
          getCdnTransformationConfig
        }}
      />,
    );
  };

  it('campaign message, add creative click whatsapp', () => {
    renderFunction('WHATSAPP', 'createTemplate', whatsappTemplates, {
      mode: 'create',
    });
    expect(renderedComponent).toMatchSnapshot();
  });

  it('campaign message, whatsapp edit min data', () => {
    renderFunction(
      'WHATSAPP',
      'editTemplate',
      whatsappTemplates,
      whatsappGetTemplateData1,
    );
    renderedComponent.instance().onEditTemplate();
    renderedComponent.find('CapSlideBox').props().content.props.handleClose();
    expect(renderedComponent).toMatchSnapshot();
    expect(handleCloseCreatives).toHaveBeenCalledTimes(1);
    expect(handleCloseCreatives).toHaveBeenCalledWith(true);
  });

  it('it should clear the url, on channel change from new whatsapp to another', () => {
    renderFunction(
      'WHATSAPP',
      'editTemplate',
      whatsappTemplates,
      whatsappGetTemplateData1,
    );
    delete window.location;
    window.location = new URL('http://127.0.0.1:3030/creatives/ui/v2?channel=whatsapp&mode=create');
    renderedComponent.instance().onEditTemplate();
    renderedComponent.find('CapSlideBox').props().content.props.handleClose();
    expect(renderedComponent).toMatchSnapshot();
    expect(handleCloseCreatives).toHaveBeenCalledTimes(1);
    expect(handleCloseCreatives).toHaveBeenCalledWith(true);
  });

  it('campaign message, whatsapp edit all data', () => {
    renderFunction(
      'WHATSAPP',
      'editTemplate',
      whatsappTemplates,
      whatsappGetTemplateData2,
    );
    renderedComponent.instance().onEditTemplate();
    renderedComponent.find('CapSlideBox').props().content.props.handleClose();
    expect(renderedComponent).toMatchSnapshot();
    expect(handleCloseCreatives).toHaveBeenCalledTimes(1);
    expect(handleCloseCreatives).toHaveBeenCalledWith(true);
  });

  it('Text getCreatives data for whatsapp, data from creatives done to campaigns', async () => {
    renderFunction(
      'WHATSAPP',
      'editTemplate',
      whatsappTemplates,
      whatsappGetCreativeData1,
    );
    renderedComponent.instance().onEditTemplate();
    renderedComponent
      .find('CapSlideBox')
      .props()
      .content.props.getFormData(whatsappGetCreativeData1);
    renderedComponent
      .find('CapSlideBox')
      .props()
      .content.props.getFormData(whatsappGetCreativeData2);
    await tick();
    expect(getCreativesData).toHaveBeenCalledTimes(2);
  });

  it('It should clear templateData, on channel change.', async () => {
    renderFunction(
      'WHATSAPP',
      'editTemplate',
      whatsappTemplates,
      whatsappGetCreativeData1,
    );
    renderedComponent.instance().onEditTemplate();
    renderedComponent
      .find('CapSlideBox')
      .props()
      .content.props.getFormData(whatsappGetCreativeData1);

    const componentInstance = renderedComponent.instance()
    expect(componentInstance.state.templateData).toBeDefined();
    expect(componentInstance.onChannelChange("MOBILEPUSH"));
    expect(componentInstance.state.templateData).toBeNull();
  });

  it('campaign message, add creative click rcs', () => {
    renderFunction('RCS', 'createTemplate', rcsTemplates, { mode: 'create' });
    expect(renderedComponent).toMatchSnapshot();
  });


// Helper function returns a promise that resolves after all other promise mocks,
// even if they are chained like Promise.resolve().then(...)
// Technically: this is designed to resolve on the next macrotask
  function tick() {
    return new Promise(resolve => {
      setTimeout(resolve, 0);
    })
  }

  it('Text getCreatives data for rcs, data from creatives done to campaigns', async () => {
    renderFunction('RCS', 'editTemplate', rcsTemplates, rcsEditTemplateData);
    renderedComponent.instance().onEditTemplate();
    renderedComponent
      .find('CapSlideBox')
      .props()
      .content.props.getFormData(rcsEditTemplateData);
    await tick();
    expect(getCreativesData).toHaveBeenCalledTimes(1);
    expect(getCreativesData).toHaveBeenCalledWith({ channel: 'RCS' });
  });

  it('RCS getFormData does not attach smsFallBackContent to templateData', async () => {
    renderFunction('RCS', 'editTemplate', rcsTemplates, rcsEditTemplateData);
    renderedComponent.instance().onEditTemplate();

    const mockValue = {
      value: {
        name: 'rcs_creative_name',
        versions: {
          base: {
            content: {
              RCS: {
                rcsContent: { contentType: 'RICHCARD', cardType: 'STANDALONE', cardSettings: {}, cardContent: [{}] },
                smsFallBackContent: { message: 'should-not-be-copied' },
              },
            },
          },
        },
      },
    };

    renderedComponent
      .find('CapSlideBox')
      .props()
      .content.props.getFormData(mockValue);
    await tick();

    const instance = renderedComponent.instance();
    expect(instance.state.templateData).toBeDefined();
    // sms fallback content should not be set on templateData per current logic
    expect(instance.state.templateData.smsFallBackContent).toBeUndefined();
  });

  it('Text getCreatives data for rcs, data from creatives done to campaigns', async () => {
    renderFunction('SMS', 'editTemplate', smsTemplates, smsEditTemplateData );
    renderedComponent.instance().onEditTemplate();
    renderedComponent
      .find('CapSlideBox')
      .props()
      .content.props.getFormData(smsEditTemplateData);
    await tick();
    expect(getCreativesData).toHaveBeenCalledTimes(1);
    expect(getCreativesData).toHaveBeenCalledWith({ channel: 'SMS'});
  });

  it('Text getCreatives data for email, data from creatives done to campaigns', async () => {
    renderFunction('EMAIL', 'editTemplate', emailTemplates, emailEditTemplateData );
    renderedComponent.instance().onEditTemplate();
    renderedComponent
      .find('CapSlideBox')
      .props()
      .content.props.getFormData(emailEditTemplateData);
    await tick();
    expect(getCreativesData).toHaveBeenCalledTimes(1);
    expect(getCreativesData).toHaveBeenCalledWith({ channel: 'EMAIL'});
  });
});
