import Button from "antd/lib/button";
import { Col } from "antd/lib/grid";
import Row from "antd/lib/row";
import { default as classNames, default as classnames } from "classnames";
import DotLoading from "components/DotLoading";
import { Icon } from "components/Icon";
import { Text } from "components/Typography";
import { useWindowSize } from "hooks";
import { useModules } from "hooks/useModules";
import reduce from "lodash/reduce";
import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import { useSelector } from "react-redux";
import { selectActiveModule } from "redux/Talent/selector";
import {
  selectTalentProfileModules,
  selectUserData,
} from "redux/User/selector";
import { IframeMessage } from "utils/iframeMessage";
import { SHOPIFY_MODULE_TYPE } from "../../../constants/shopify";
import { selectShopifyStores } from "../../../redux/Shopify/selector";
import "./ProfilePreview.scss";
import ProfilePreviewModal from "./ProfilePreviewModal";
import config from "config";
import { FLAGS, useFeatureIsOn } from "@komi-app/flags-sdk";
import { useCurrentProfilePreviewUrl } from "../../../hooks/useCurrentProfilePreviewUrl";

import { ModuleType } from "@komi-app/shared-types";

export const DEVICE_TYPE = {
  MOBILE: "mobile",
  TABLET: "tablet",
  DESKTOP: "desktop",
};

const CONSUMER_URL = config.client.url;
const TALENT_PREVIEW_URL = CONSUMER_URL + "/talent-profile-preview";

interface ProfilePreviewProps {
  fullWidth?: boolean;
  hideControls?: boolean;
}

const ProfilePreview: React.FC<ProfilePreviewProps> = ({
  fullWidth = false,
  hideControls = false,
  ...props
}) => {
  const iframeRef = useRef<HTMLIFrameElement | null>(null);
  const { width } = useWindowSize();

  const isProfilePreviewUrlDomainFixEnabled = useFeatureIsOn(
    FLAGS.FIX_SB_869_PREVIEW_NOT_PLAYING_VIDEOS
  );
  const profilePreviewUrl = useCurrentProfilePreviewUrl();

  const user = useSelector(selectUserData);

  const talentProfileModules = useSelector(selectTalentProfileModules);

  const stores = useSelector(selectShopifyStores);
  const activeModule = useSelector(selectActiveModule);

  const [webLoaded, setWebLoaded] = useState(false);
  const [webRect, setWebRect] = useState<DOMRect>();
  const [deviceType, setDeviceType] = useState("mobile");
  const [showPreviewMessage, setShowPreviewMessage] = useState(
    !(localStorage.getItem("SHOWED_PREVIEW_MESSAGE") === "true")
  );
  const [showModal, toggleModal] = useState(false);
  const { thirdPartyData } = useModules();
  const currentModules = useMemo(() => {
    return reduce(
      talentProfileModules,
      (result: any, item: any) => {
        if (
          [
            ModuleType.SHOP_MY_SHELF,
            ModuleType.SHOP_LIST,
            ModuleType.YOUTUBE_COLLECTION,
            ModuleType.BANDSINTOWN,
            ModuleType.PODCAST_AUTOMATION,
            ModuleType.SEATED,
          ].includes(item.type)
        ) {
          const data = thirdPartyData.find((el: any) => el.id === item.id);
          let items;
          switch (item.type) {
            case ModuleType.SHOP_MY_SHELF:
            case ModuleType.SHOP_LIST:
              items = data?.products;
              break;
            case ModuleType.YOUTUBE_COLLECTION:
              items = data?.collection?.items;
              break;
            case ModuleType.BANDSINTOWN:
              items = data?.events || [];
              break;
            case ModuleType.SEATED:
              items = data?.events?.shows || [];
              break;
            case ModuleType.PODCAST_AUTOMATION:
              items = data?.collection?.items || [];
              break;
            default:
              break;
          }
          return [
            ...result,
            {
              ...item,
              items: items || [],
              displayLatest: item.items[0].activeLatestPodcast,
            },
          ];
        }
        if (item.type === ModuleType.GROUP) {
          const items = reduce(
            item.items,
            (newItems: any, element: any) => {
              if (
                [
                  ModuleType.SHOP_MY_SHELF,
                  ModuleType.SHOP_LIST,
                  ModuleType.YOUTUBE_COLLECTION,
                  ModuleType.BANDSINTOWN,
                  ModuleType.SEATED,
                  ModuleType.PODCAST_AUTOMATION,
                ].includes(element.type as ModuleType)
              ) {
                const data = thirdPartyData.find(
                  (el: any) => el.id === element.id
                );

                let items;
                switch (element.type) {
                  case ModuleType.SHOP_MY_SHELF:
                  case ModuleType.SHOP_LIST:
                    items = data?.products;
                    break;
                  case ModuleType.YOUTUBE_COLLECTION:
                    items = data?.collection?.items;
                    break;

                  case ModuleType.BANDSINTOWN:
                    items = data?.events || [];
                    break;
                  case ModuleType.SEATED:
                    items = data?.events?.shows || [];
                    break;
                  case ModuleType.PODCAST_AUTOMATION:
                    items = data?.collection?.items || [];
                    break;
                  default:
                    break;
                }

                return [
                  ...newItems,
                  {
                    ...element,
                    displayLatest: element.items[0].activeLatestPodcast,
                    items: items || [],
                  },
                ];
              }
              return [...newItems, element];
            },
            []
          );

          return [
            ...result,
            {
              ...item,
              items,
            },
          ];
        }
        return [...result, item];
      },
      []
    );
  }, [thirdPartyData, talentProfileModules]);

  const shopifyMerchants = useMemo(() => {
    return talentProfileModules?.reduce((result: any, item) => {
      if (
        [
          SHOPIFY_MODULE_TYPE.SHOPIFY_COLLECTION,
          SHOPIFY_MODULE_TYPE.SHOPIFY_PRODUCT,
        ].includes(item.type)
      ) {
        const storeDomain = (item.items?.[0] as any)?.shop || "";

        const accessToken =
          stores?.find((store) => store.domain === storeDomain)?.accessToken ||
          user?.talentProfile?.shopifyMerchants?.[storeDomain]?.accessToken;
        result[storeDomain] = accessToken;
        return result;
      }
      return result;
    }, {});
  }, [stores, user, talentProfileModules]);

  const handleSendTalentProfile = useCallback(async () => {
    if (!iframeRef) return;
    const message = {
      type: "komi_talent_profile",
      data: {
        ...user,
        talentProfile: {
          ...user?.talentProfile,
          modules: currentModules,
          shopifyMerchants,
        },
      },
    };
    iframeRef.current?.contentWindow?.postMessage(JSON.stringify(message), "*");
    IframeMessage.postMessage(message);

    // trigger scroll 1px to load lazy image
    // window.scrollTo(window.scrollX, window.scrollY + 1);
  }, [user, currentModules, shopifyMerchants]);

  const handleMessage = useCallback(
    async (event: MessageEvent) => {
      const { type, data } = event.data;
      if (!showModal) {
        switch (type) {
          case "komi_consumer_loaded":
            setWebLoaded(true);
            handleSendTalentProfile();
            break;
          case "komi_consumer_rect":
            if (!!data.height) {
              setWebRect(data);
            }
            break;
          default:
            break;
        }
      }
    },
    [webLoaded, user, talentProfileModules, handleSendTalentProfile, showModal]
  );

  useEffect(() => {
    IframeMessage.bindEvent(window, "message", handleMessage);
    return () => {
      IframeMessage.unbindEvent(window, "message", handleMessage);
    };
  }, [handleMessage]);

  useEffect(() => {
    handleSendTalentProfile();
  }, [shopifyMerchants, talentProfileModules, handleSendTalentProfile]);

  useEffect(() => {
    if (!webLoaded) return;
    iframeRef?.current?.setAttribute(
      "style",
      `height:${webRect?.height || 10000}px`
    );
  }, [webRect, webLoaded]);

  useEffect(() => {
    if (!!activeModule) {
      if (!iframeRef) return;
      const message = {
        type: "komi_talent_profile_active_module",
        data: {
          activeModule,
        },
      };
      iframeRef.current?.contentWindow?.postMessage(
        JSON.stringify(message),
        "*"
      );
      IframeMessage.postMessage(message);
    }
  }, [iframeRef, activeModule]);

  return (
    <div
      className="profile-preview-wrapper"
      style={{
        width: fullWidth
          ? "100%"
          : width
            ? width >= 1138
              ? 337
              : (width - 96) / 3
            : 337,
        maxWidth: "100%",
        height: "100%",
      }}
      {...props}
    >
      {showPreviewMessage && (
        <Row className="preview-message" justify="center" align="middle">
          <Icon name="view" />
          <Text>This is a preview</Text>
          <Button
            className="p--0"
            type="text"
            onClick={() => {
              setShowPreviewMessage(false);
              localStorage.setItem("SHOWED_PREVIEW_MESSAGE", "true");
            }}
          >
            <Icon name="close-outline" />
          </Button>
        </Row>
      )}
      {(!webLoaded || !webRect?.height) && (
        <div
          className={classnames({
            "preview-loading": true,
          })}
        >
          <DotLoading isDarken={false} />
        </div>
      )}
      <iframe
        ref={iframeRef}
        id="consumer-web"
        className={fullWidth ? "consumer-web-full-width" : ""}
        src={
          isProfilePreviewUrlDomainFixEnabled
            ? profilePreviewUrl
            : `${TALENT_PREVIEW_URL}`
        }
        frameBorder="0"
      />
      {!hideControls && (
        <div className="preview-device-type-wrapper">
          <div className="preview-device-type">
            <Row className="p--4" gutter={16}>
              <Col className="height--48">
                <Button
                  type="text"
                  className={classNames({
                    "p--0": true,
                    active: deviceType === DEVICE_TYPE.MOBILE,
                  })}
                  onClick={() => setDeviceType(DEVICE_TYPE.MOBILE)}
                >
                  <Icon name="mobile" />
                </Button>
              </Col>
              <Col className="height--48">
                <Button
                  type="text"
                  className={classNames({
                    "p--0": true,
                    active: deviceType === DEVICE_TYPE.TABLET,
                  })}
                  onClick={() => {
                    setDeviceType(DEVICE_TYPE.TABLET);
                    toggleModal(true);
                  }}
                >
                  <Icon name="tablet" />
                </Button>
              </Col>
              <Col>
                <Button
                  type="text"
                  className={classNames({
                    "p--0": true,
                    active: deviceType === DEVICE_TYPE.DESKTOP,
                  })}
                  onClick={() => {
                    setDeviceType(DEVICE_TYPE.DESKTOP);
                    toggleModal(true);
                  }}
                >
                  <Icon name="desktop" />
                </Button>
              </Col>
            </Row>
          </div>
        </div>
      )}
      {showModal && (
        <ProfilePreviewModal
          deviceType={deviceType}
          show={showModal}
          onCancel={() => {
            setDeviceType(DEVICE_TYPE.MOBILE);
            toggleModal(false);
          }}
        />
      )}
    </div>
  );
};

export default ProfilePreview;
