/*
 *
 * CapFacebookPreview
 *
 */
import PropTypes from 'prop-types';
import React, { useState, useEffect} from "react";
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { createStructuredSelector } from 'reselect';
import { injectIntl, FormattedMessage, intlShape } from 'react-intl';
import {makeSelectCapFacebookPreview} from './selectors';

import messages from './messages';
import * as actions from './actions';
import {
  CapLabel,
  CapSelect,
  CapButton,
  CapImage,
  CapSpin,
  CapIcon,
  CapNotification,
  CapTooltip,
} from "@capillarytech/cap-ui-library";
import facebookEmptyPlaceholder from '../../assets/facebookEmptyPlaceholder.png';
import {
  IMAGE,
  VIDEO,
  CAROUSEL,
  NO_CALL_TO_ACTION,
} from '../../v2Containers/Facebook/Advertisement/constant';
import {
  FETCH_PREVIEW_REQUESTED,
  FETCH_PREVIEW_SUCCESS,
  PREVIEW_NOT_REQUESTED,
} from './constants';
import './index.scss';
import injectSaga from '../../utils/injectSaga';
import injectReducer from '../../utils/injectReducer';
import { v2CapFacebookPreviewSagas } from './sagas';
import v2CapFacebookPreviewReducer from './reducer';
import { compose } from 'redux';

export const CapFacebookPreview = (props) => {
  const {
    intl,
    disablePreviewButton,
    previewData,
    facebookPreviewActions,
    facebookPreviewData = {},
    selectedAd,
    primaryText,
    callToAction,
    orgUnitFacebookPageSettingsMap = {},
    accessToken,
    accountId,
    defaultGeneratePreview,
    hideInfoText = false,
  } = props;
  const {
    formatMessage,
    } = intl || {};
  const [adPreviewFormat, setAdPreviewFormat] = useState("DESKTOP_FEED_STANDARD");
  const [disableAfterPreviewGenerate, setDisableAfterPreviewGenerate] = useState(false);
  const [random, setRandom] = useState(0);
  const {pageAccessToken, pageId} = orgUnitFacebookPageSettingsMap;
  const {previewIframe = "", fetchPreviewStatus = PREVIEW_NOT_REQUESTED, previewIframeError = ""} = facebookPreviewData;
  const [previewLoaded, setPreviewLoaded] = useState(false);
  const [isRefreshing, setIsRefreshing] = useState(false);
  let isSpinning = false;
  const facebookAdOptions = [
    {
      value: "DESKTOP_FEED_STANDARD",
      label: formatMessage(messages.desktopFeedStandard),
    },
    {
      value: "FACEBOOK_STORY_MOBILE",
      label: formatMessage(messages.facebookStoryMobile),
    },
    {
      value: "INSTANT_ARTICLE_STANDARD",
      label: formatMessage(messages.instantArticleStandard),
    },
    {
      value: "INSTREAM_VIDEO_DESKTOP",
      label: formatMessage(messages.instreamVideoDesktop),
    },
    {
      value: "INSTREAM_VIDEO_MOBILE",
      label: formatMessage(messages.instreamVideoMobile),
    },
    {
      value: "MARKETPLACE_DESKTOP",
      label: formatMessage(messages.marketplaceDesktop),
    },
    {
      value: "MOBILE_FEED_BASIC",
      label: formatMessage(messages.mobileFeedBasic),
    },
    {
      value: "MARKETPLACE_MOBILE",
      label: formatMessage(messages.marketplaceMobile),
    },
    {
      value: "MOBILE_FEED_STANDARD",
      label: formatMessage(messages.mobileFeedStandard),
    },
    {
      value: "RIGHT_COLUMN_STANDARD",
      label: formatMessage(messages.rightColumnStandard),
    },
    {
      value: "SUGGESTED_VIDEO_DESKTOP",
      label: formatMessage(messages.suggestedVideoDesktop),
    },
    {
      value: "SUGGESTED_VIDEO_MOBILE",
      label: formatMessage(messages.suggestedVideoMobile),
    },
    {
      value: "WATCH_FEED_MOBILE",
      label: formatMessage(messages.watchFeedMobile),
    },
  ];
  const instaAdOptions = [
    {
      value: "INSTAGRAM_STANDARD",
      label: formatMessage(messages.instagramStandard),
    },
    {
      value: "INSTAGRAM_STORY",
      label: formatMessage(messages.instagramStory),
    },
    {
      value: "INSTAGRAM_EXPLORE_CONTEXTUAL",
      label: formatMessage(messages.instagramExploreContextual),
    },
    {
      value: "INSTAGRAM_EXPLORE_IMMERSIVE",
      label: formatMessage(messages.instagramExploreImmersive),
    },
  ];
  const messangerAdOptions = [
    {
      value: "MESSENGER_MOBILE_INBOX_MEDIA",
      label: formatMessage(messages.messengerMobileInboxMedia),
    },
  ];
  const audienceNetworkOptions = [
    {
      value: "AUDIENCE_NETWORK_INSTREAM_VIDEO",
      label: formatMessage(messages.audienceNetworkInstreamVideo),
    },
    {
      value: "AUDIENCE_NETWORK_INSTREAM_VIDEO_MOBILE",
      label: formatMessage(messages.audienceNetworkInstreamVideoMobile),
    },
    {
      value: "AUDIENCE_NETWORK_OUTSTREAM_VIDEO",
      label: formatMessage(messages.audienceNetworkOutstreamVideo),
    },
    {
      value: "AUDIENCE_NETWORK_REWARDED_VIDEO",
      label: formatMessage(messages.audienceNetworkRewardedVideo),
    },
    {
      value: "MOBILE_BANNER",
      label: formatMessage(messages.mobileBanner),
    },
    {
      value: "MOBILE_FULLWIDTH",
      label: formatMessage(messages.mobileFullwidth),
    },
    {
      value: "MOBILE_INTERSTITIAL",
      label: formatMessage(messages.mobileInterstitial),
    },
    {
      value: "MOBILE_MEDIUM_RECTANGLE",
      label: formatMessage(messages.mobileMediumRectangle),
    },
    {
      value: "MOBILE_NATIVE",
      label: formatMessage(messages.mobileNative),
    },
  ];

  const adOptions = [
    ...facebookAdOptions,
    ...instaAdOptions,
    ...messangerAdOptions,
    ...audienceNetworkOptions,
  ];
  const onChangeAdPreviewFormat = (value) => {
    setAdPreviewFormat(value);
    setDisableAfterPreviewGenerate(false);
  };

  const generatePreview = () => {
    const data = {
      accessToken,
      pageAccessToken,
      pageId,
      actId: `act_${accountId}`,
      params: {
        creative: {
          object_story_spec: {
            page_id: pageId,
          },
        },
        ad_format: adPreviewFormat,
      },
    };
    const { webSiteLink= "" } = (previewData || [] )[0] || {};
    if (selectedAd !== CAROUSEL) {
      const {
         imageData = {},
         webSiteLink,
         linkDesc,
         linkHeadLine,
         subType,
         videoData,
        } = previewData[0];
      if (subType === IMAGE) {
        data.params.creative.object_story_spec = {
          ...data.params.creative.object_story_spec,
          link_data: {
            description: linkDesc,
            message: primaryText,
            link: webSiteLink,
            name: linkHeadLine,
            picture: imageData.imageSrc,
          } };
        if (callToAction !== NO_CALL_TO_ACTION) {
          data.params.creative.object_story_spec.link_data.call_to_action = {
            type: callToAction,
            value: {link: webSiteLink},
          };
        }
        facebookPreviewActions.getPreview(data);
      } else {
        data.params.creative.object_story_spec.video_data = {
          image_url: videoData.previewUrl,
          video_id: videoData.videoId,
          message: primaryText,
          link_description: linkDesc,
        };
        if (callToAction !== NO_CALL_TO_ACTION) {
          data.params.creative.object_story_spec.video_data.call_to_action = {
            type: callToAction,
            value: {link: webSiteLink},
          };
        }
        facebookPreviewActions.getPreview(data);
      }
    } else {
      const childData = previewData.map((obj) => {
        let arrayData = {
          link: obj.webSiteLink,
          name: obj.linkHeadLine,
          description: obj.linkDesc,
        };
        if (callToAction !== NO_CALL_TO_ACTION) {
          arrayData.call_to_action = {
            type: callToAction,
            value: {link: obj.webSiteLink},
          };
        }
        if (obj.subType === VIDEO) {
          arrayData = {
            ...arrayData,
            video_id: obj.videoData.videoId,
            picture: obj.videoData.previewUrl,
          };
        } else {
          arrayData = {
            ...arrayData,
            picture: obj.imageData.imageSrc,
          };
        }
        return arrayData;
      });
      data.params.creative.object_story_spec = {
        ...data.params.creative.object_story_spec,
        link_data: {
          message: primaryText,
          child_attachments: childData,
          multi_share_end_card: false,
          "link":webSiteLink,
        },
      };
      facebookPreviewActions.getPreview(data);
    }
    setDisableAfterPreviewGenerate(true);
  };

  const resetIframe = () => {
    previewLoaded && setPreviewLoaded(false);
    !isRefreshing && setIsRefreshing(true);
    const r = random + 1;
    setRandom(r);
  };
  const unsetLoader = () => {
    setTimeout(function() { 
      !previewLoaded && setPreviewLoaded(true);
      isRefreshing && setIsRefreshing(false);
    }.bind(this), 5000);
  }
  const getIframe = (iframe) => {
    const divTag = document.createElement('div');
    divTag.innerHTML = iframe;
    const src = divTag.getElementsByTagName('iframe')[0].getAttribute('src');
    return (<>
      <iframe
        src={src}
        key={random}
        style={{ border: "none" }}
        width={"600px"}
        scrolling="no"
        height={"1000px"}
        className="cap-facebook-ad-iframe"
        onLoad={
          unsetLoader()
        }
      />
    </>);
  };

  const showRefreshButton = () => {
    let isRefresh = false;
    props.previewData.forEach((obj) => {
      if (obj.subType === VIDEO) {
        isRefresh = true;
        return isRefresh;
      }
    });
    return isRefresh && previewIframe !== "";
  };
  const isRefreshButton = showRefreshButton();

  useEffect(() => {
    facebookPreviewActions.clearPreview();
    if (defaultGeneratePreview) {
      generatePreview();
    }
  }, []);

  useEffect(() => {
    if (disableAfterPreviewGenerate) {
      setDisableAfterPreviewGenerate(false);
    }
  }, [previewData,
    primaryText,
    callToAction]);

  useEffect(() => {
    if (previewIframeError) {
      CapNotification.error({
        message: formatMessage(messages.generatePreviewError),
      });
      setDisableAfterPreviewGenerate(false);
    }
  }, [previewIframeError]);
  return (
    <>
      {isSpinning = (fetchPreviewStatus === FETCH_PREVIEW_REQUESTED) ||
        ((fetchPreviewStatus === FETCH_PREVIEW_SUCCESS) && !previewLoaded) ||
        isRefreshing}
      <CapSpin
        spinning={isSpinning}>
        <div style={{ display: 'inline-block' }}>
          <CapSelect
            label={formatMessage(messages.previewBasedonAdPlacement)}
            key={"select-previewBasedonAdPlacement"}
            onChange={onChangeAdPreviewFormat}
            style={{ width: '328px', paddingBottom: 16 }}
            options={adOptions}
            value={adPreviewFormat}
          >
          </CapSelect>
        </div>
        {!hideInfoText && <CapLabel
          type="label1"
          style={{ paddingBottom: 16, textAlign: 'left', width: 392 }}
        >
          {formatMessage(messages.previewAdDesc)}
        </CapLabel>}
        <div style={{ marginBottom: 16 }}>
          {(disablePreviewButton || disableAfterPreviewGenerate) ?
            <CapTooltip title={formatMessage(messages.generatePreviewDisableToolTip)}>
              <div className="button-disabled-tooltip-wrapper">
                <CapButton
                  type="secondary"
                  disabled
                >
                  <FormattedMessage {...messages.generatePreview} />
                </CapButton>
              </div>
            </CapTooltip> :
            <CapButton
              type="secondary"
              onClick={generatePreview}
            >
              <FormattedMessage {...messages.generatePreview} />
            </CapButton>}
          {isRefreshButton && (<CapButton
            onClick={resetIframe}
            type="secondary"
            style={{ marginLeft: 16 }}
          >
            {formatMessage(messages.refreshPreview)}
          </CapButton>)}
        </div>
        {isRefreshButton && <div style={{ marginBottom: 16 }}>
          <CapIcon
            type="info"
            svgProps={{
              width: 16,
              height: 16,
            }}
          >
          </CapIcon>
          <CapLabel.CapLabelInline
            type="label1"
            size="s"
            style={{ marginBottom: 16, width: 392 }}
          >
            {formatMessage(messages.videoNotePreview)}
          </CapLabel.CapLabelInline>
        </div>}
        {previewIframe === "" ? <CapImage
          src={facebookEmptyPlaceholder}
          alt="default"
          width="316px"
          height="392px"
        /> : getIframe(previewIframe)}
      </CapSpin>
    </>
  );
};

CapFacebookPreview.propTypes = {
  disablePreviewButton: PropTypes.bool,
  intl: intlShape,
  previewData: PropTypes.array,
  selectedAd: PropTypes.string,
  facebookPreviewActions: PropTypes.func,
  facebookPreviewData: PropTypes.any,
  primaryText: PropTypes.string,
  callToAction: PropTypes.string,
  orgUnitFacebookPageSettingsMap: PropTypes.object,
  accessToken: PropTypes.string,
  accountId: PropTypes.string,
  hideInfoText:PropTypes.any,
};

const mapStateToProps = createStructuredSelector({
  facebookPreviewData: makeSelectCapFacebookPreview(),
});

const mapDispatchToProps = (dispatch) => ({
  facebookPreviewActions: bindActionCreators(actions, dispatch),
});

const withConnect = connect(mapStateToProps, mapDispatchToProps);
const withSaga = injectSaga({ key: 'facebookPreview', saga: v2CapFacebookPreviewSagas });
const withReducer = injectReducer({ key: 'facebookPreview', reducer: v2CapFacebookPreviewReducer });

export default compose(withSaga, withReducer, withConnect)(injectIntl(CapFacebookPreview));
