import Button from "antd/lib/button";
import List from "antd/lib/list";
import classNames from "classnames";
import ContentCard from "components/ContentCard";
import DragDropContext from "components/DragDropContext";
import Experience1To1Modal from "components/Experience1To1Modal/Experience1To1Modal";
import ExperienceContentCard from "components/ExperienceContentCard";
import ExperienceLiveClassModal from "components/ExperienceInterActiveLiveClassModal";
import { Icon } from "components/Icon";
import PortalComponent from "components/PortalComponent/PortalComponent";
import SelectContentTypeModal from "components/SelectContentTypeModal";
import { SelectContentItem } from "components/SelectContentTypeModal/SelectContentTypeModal";
import { Text } from "components/Typography";
import { SEGMENT_EVENTS } from "constants/segment";
import { useAnalytics } from "hooks/useAnalytics";
import { useModules } from "hooks/useModules";
import { ReactComponent as OneToOneIcon } from "icons/1-to-1.svg";
import { ReactComponent as BroadcastIcon } from "icons/live.svg";
import {
  ExperienceItem,
  TalentProfileModule,
} from "models/talent/talent-profile-module.model";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { DraggableProvidedDragHandleProps } from "react-beautiful-dnd";
import { EXPERIENCE_TYPE } from "redux/Experience/types";
import { useTypedSelector } from "redux/rootReducer";
import { selectLocalizationSelected } from "redux/User/selector";
import { ArrayServices } from "utils/array";
import { isEmptyModule } from "utils/modules";
import ModuleEditor from "../ModuleEditor";
import EmptyModule from "./EmptyModule";
import "./ModuleExperience.scss";
import { useCreatorTracking, CreatorEvent } from "@komi-app/analytics-sdk";
import { trackingProps } from "utils/tracking";
import { FLAGS, useFeatureIsOn } from "@komi-app/flags-sdk";

const types: SelectContentItem[] = [
  {
    name: EXPERIENCE_TYPE.ONE_TO_ONE,
    title: "Meet and greet",
    description: "Enable fans to meet you one-on-one via live video",
    icon: <OneToOneIcon />,
  },
  {
    name: EXPERIENCE_TYPE.INTERACTIVE_LIVE_CLASS,
    title: "Live",
    description:
      "Host a live stream with up to 10 people and stream that to up to a million fans",
    icon: <BroadcastIcon />,
  },
];
interface ModuleExperienceProps {
  module: TalentProfileModule<ExperienceItem>;
  dragHandleProps?: DraggableProvidedDragHandleProps;
  active: boolean;
}

const ModuleExperience: React.FC<ModuleExperienceProps> = ({
  module,
  dragHandleProps,
  active,
}) => {
  const { sendSegmentEvent } = useAnalytics();
  const profileContext = useModules();
  const [items, setItems] = useState<ExperienceItem[]>([]);
  const [itemsError, setItemsError] = useState<ExperienceItem[]>([]);
  const [showContentModal, setShowContentModal] = useState(false);
  const [selectedContentType, setSelectedContentType] =
    useState<EXPERIENCE_TYPE>();
  const [experienceEditState, setExperienceEditState] = useState<{
    isEdit: boolean;
    experience?: ExperienceItem;
  }>({
    isEdit: false,
  });
  const localizationSelected = useTypedSelector(selectLocalizationSelected);

  const totalPriceOfItems = useMemo(() => {
    return module.items.reduce(
      (acc, curr) => (acc += curr.experiencePrice || 0),
      0
    );
  }, [module]);

  const useAnalyticsSDK = useFeatureIsOn(FLAGS.USE_ANALYTICS_SDK_TALENT);
  const { createTracker } = useCreatorTracking()
  const elementCreate = createTracker(CreatorEvent.ELEMENT_CREATED);

  useEffect(() => {
    setItems(
      module.items.map((item, index) => ({
        ...item,
        order: index,
      }))
    );

    setItemsError(
      module.items.filter(
        (item) => item.isSuccess === false && typeof item.error === "string"
      )
    );
    return () => {};
  }, [module.items, module.visible]);

  const handleSubmitType = useCallback(
    (type: EXPERIENCE_TYPE) => {
      setShowContentModal(false);
      setSelectedContentType(type);
    },
    [module]
  );

  const onEditModuleCallback = useCallback(
    (moduleEdit: TalentProfileModule<ExperienceItem>) => {
      profileContext.setModule(moduleEdit);
    },
    [profileContext.setModule]
  );

  const onAddItem = useCallback(() => {
    setExperienceEditState((preState) => ({
      ...preState,
      isEdit: false,
      experience: undefined,
    }));
    setSelectedContentType(undefined);
    setShowContentModal(true);
  }, []);

  const onEditItem = useCallback(
    (item: ExperienceItem) => {
      setExperienceEditState((preState) => ({
        ...preState,
        isEdit: true,
        experience: item,
      }));
      setSelectedContentType(item.type);
    },
    [module]
  );

  const onDeleteItem = useCallback(
    (item: ExperienceItem) => {
      profileContext.setModule({
        ...module,
        items: ArrayServices.removeWithIndex(
          module.items,
          item.order as number
        ),
        isUpdate: true,
      });
    },
    [module, profileContext.setModule]
  );

  const onDropEndItems = useCallback(
    (list: ExperienceItem[]) => {
      onEditModuleCallback({
        ...module,
        items: list.map((item, index) => ({
          ...item,
          experienceId: item.id,
          order: index,
        })),
        isUpdate: true,
      });
    },
    [module, onEditModuleCallback]
  );

  const toggleContentModal = useCallback((value: boolean) => {
    setShowContentModal(value);
  }, []);

  const onSaveExperienceCallback = useCallback(
    (experience: ExperienceItem) => {
      let moduleEdit;
      if (experienceEditState.isEdit) {
        moduleEdit = {
          ...module,
          items: ArrayServices.updateWithIndex(
            module.items,
            experienceEditState.experience?.order as number,
            experience
          ),
          isUpdate: true,
        };
      } else {
        moduleEdit = {
          ...module,
          items: ArrayServices.unshift(module.items, experience),
          isUpdate: true,
        };
      }
      profileContext.setModule(moduleEdit);

      const {
        pageId,
        pageName,
        type
      } = trackingProps(moduleEdit.type, localizationSelected)

      useAnalyticsSDK
        ? elementCreate({ pageId, pageName, type })
        : sendSegmentEvent(SEGMENT_EVENTS.ELEMENT_CREATED, {
            "Module Type": moduleEdit.type,
            "Page ID": localizationSelected?.id || null,
            "Page Name": localizationSelected?.name || "Default",
          });
    },
    [
      module,
      experienceEditState,
      localizationSelected,
      profileContext.setModule,
    ]
  );

  return (
    <React.Fragment>
      <SelectContentTypeModal
        defaultValue={EXPERIENCE_TYPE.ONE_TO_ONE}
        show={showContentModal}
        toggleModal={toggleContentModal}
        handleSubmit={handleSubmitType}
        types={types}
      />
      <Experience1To1Modal
        show={selectedContentType === EXPERIENCE_TYPE.ONE_TO_ONE}
        item={experienceEditState.experience}
        isEdit={experienceEditState.isEdit}
        toggleModal={() => {
          setSelectedContentType(undefined);
        }}
        onCancel={() => {
          setSelectedContentType(undefined);
          setShowContentModal(true);
        }}
        onConfirmCallback={onSaveExperienceCallback}
      />
      <ExperienceLiveClassModal
        show={selectedContentType === EXPERIENCE_TYPE.INTERACTIVE_LIVE_CLASS}
        item={experienceEditState.experience}
        isEdit={experienceEditState.isEdit}
        toggleModal={() => {
          setSelectedContentType(undefined);
        }}
        onCancel={() => {
          setSelectedContentType(undefined);
          setShowContentModal(true);
        }}
        onConfirmCallback={onSaveExperienceCallback}
      />
      <ModuleEditor
        module={module}
        showStripeWarning={totalPriceOfItems > 0}
        dragHandleProps={dragHandleProps}
        banner={
          <ContentCard
            className="m__t--24"
            contentClassName="m__l--0"
            type="error"
            show={itemsError.length > 0}
            content={
              <List
                className="p--0"
                size="small"
                dataSource={itemsError}
                renderItem={(item, index) => (
                  <List.Item key={index}>
                    <b>{item.name}</b>: {item.error}
                  </List.Item>
                )}
              />
            }
            handleClose={() => setItemsError([])}
          />
        }
      >
        {isEmptyModule(module) ? (
          <React.Fragment>
            <EmptyModule titleAction="Add New Experience" onClick={onAddItem} />
          </React.Fragment>
        ) : (
          <React.Fragment>
            <Button
              className="add-item-btn m__b--22 p__y--0 height--32"
              type="text"
              onClick={onAddItem}
            >
              <div className="d--flex justify__content--center align__items--center ">
                <Icon name="add-blue" />
                <Text preset="semibold18" className="text--blue m__l--4">
                  Add New Experience
                </Text>
              </div>
            </Button>
            <DragDropContext
              droppableId="experience-child-drop"
              listClassName="experience-list"
              itemIdPrefix="experience"
              direction="vertical"
              list={items}
              onDropEndCallback={onDropEndItems}
            >
              {(dragProvided, snapshot, item, itemIndex) => {
                const isRender = active ? active : itemIndex < 2;

                return isRender ? (
                  <PortalComponent
                    innerRef={dragProvided.innerRef}
                    key={itemIndex}
                    namespaceClass="experience-list"
                    provided={dragProvided}
                    snapshot={snapshot}
                  >
                    <ExperienceContentCard
                      cardClass={classNames({
                        "m__b--0": true,
                        "experience-content-card__has-error":
                          item.isSuccess === false,
                      })}
                      disableDragDrop={module.items.length <= 1}
                      content={item}
                      titleShortcut
                      dragHandleProps={dragProvided.dragHandleProps}
                      onEdit={onEditItem}
                      onDelete={onDeleteItem}
                    />
                  </PortalComponent>
                ) : (
                  <></>
                );
              }}
            </DragDropContext>
            {!active && items.length > 2 && (
              <div className="d--flex justify__content--end align__items--center m__t--20 cursor-pointer">
                <Text preset="medium14" className="opacity-6">
                  +{items.length - 2} More
                </Text>
              </div>
            )}
          </React.Fragment>
        )}
      </ModuleEditor>
    </React.Fragment>
  );
};

export default React.memo(ModuleExperience);
