import React, { useCallback, useEffect, useRef, useState } from "react";

import { useDispatch, useSelector } from "react-redux";

import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import { setContainerLastFocusedElement } from "@enact/spotlight/src/container";

import {
  sendLogMyPageMyDelete,
  sendLogTotalRecommend,
} from "../../../../actions/logActions";
import {
  clearFavorites,
  deleteMyFavorite,
  getMyFavorite,
} from "../../../../actions/myPageActions";
import {
  popPanel,
  pushPanel,
  updatePanel,
} from "../../../../actions/panelActions";
import TBody from "../../../../components/TBody/TBody";
import TButton, { TYPES } from "../../../../components/TButton/TButton";
import TCheckBox from "../../../../components/TCheckBox/TCheckBox";
import THeader from "../../../../components/THeader/THeader";
import TVerticalPagenator from "../../../../components/TVerticalPagenator/TVerticalPagenator";
import usePrevious from "../../../../hooks/usePrevious";
import {
  LOG_CONTEXT_NAME,
  LOG_MESSAGE_ID,
  panel_names,
} from "../../../../utils/Config";
import { $L } from "../../../../utils/helperMethods";
import { SpotlightIds } from "../../../../utils/SpotlightIds";
import MyPageItemCard, { SIZES } from "../../MyPageItemCard/MyPageItemCard";
import css from "../Favorites/Favorites.module.less";

const HeaderButtonContainer = SpotlightContainerDecorator("div");
const ContainerBasic = SpotlightContainerDecorator({ enterTo: null }, "div");
export default function Favorites({ title, panelInfo, isOnTop }) {
  const dispatch = useDispatch();

  const favoritesDatas = useSelector(
    (state) => state.myPage.favoriteData.favorites
  );
  const showLoadingPanel = useSelector(
    (state) => state.common.appStatus.showLoadingPanel
  );
  const [activeDelete, setActiveDelete] = useState(false);
  const [selectedItems, setSelectedItems] = useState({});
  const [selectAll, setSelectAll] = useState(false);
  const [loading, setLoading] = useState(true);
  const spotRestoredRef = useRef(false);

  let timerRef = useRef();

  const cbChangePageRef = useRef(null);
  const focusedContainerIdRef = useRef(null);

  useEffect(() => {
    if (isOnTop && !loading) {
      setTimeout(() => {
        if (activeDelete) {
          Spotlight.focus("favorites_header");
          return;
        }
        let ret = null;
        if (!spotRestoredRef.current && panelInfo.currentSpot) {
          ret = Spotlight.focus(panelInfo.currentSpot);
        }
        if (ret) {
          spotRestoredRef.current = true;
        } else {
          if (favoritesDatas && favoritesDatas.length > 0) {
            Spotlight.focus(SpotlightIds.MY_PAGE_FAVORITES_BOX);
          } else {
            Spotlight.focus("mypage-favorites-nodata");
          }
        }
      }, 0);
    }
  }, [isOnTop, loading, panelInfo, favoritesDatas]);

  useEffect(() => {
    clearTimeout(timerRef.current);
    timerRef.current = setTimeout(() => {
      setLoading(showLoadingPanel.show);
    }, 100);
  }, [dispatch, showLoadingPanel]);

  useEffect(() => {
    dispatch(getMyFavorite());
  }, [dispatch, panelInfo]);

  useEffect(() => {
    return () => {
      timerRef.current && clearTimeout(timerRef.current);
    };
  }, [dispatch]);

  useEffect(() => {
    const initialSelectedItems = favoritesDatas?.reduce((acc, item, index) => {
      acc[item.prdtId] = false;

      return acc;
    }, {});

    setSelectedItems(initialSelectedItems ?? {});
  }, [favoritesDatas]);

  const handleDeleteBtnClick = useCallback(() => {
    if (activeDelete) {
      const updatedSelectedItems = Object.keys(selectedItems).reduce(
        (acc, key) => {
          if (selectedItems[key]) {
            acc[key] = false;
          } else {
            acc[key] = selectedItems[key];
          }

          return acc;
        },
        {}
      );

      setSelectedItems(updatedSelectedItems);
      setSelectAll(false);

      let productList = [];
      let showList = [];
      let deleteList = [];

      Object.entries(selectedItems).forEach(([id, selected]) => {
        if (selected) {
          const item = favoritesDatas.find(
            (item) => item.prdtId === id || item.showId === id
          );
          if (item.prdtId === id) {
            productList.push({ patnrId: item.patnrId, prdtId: item.prdtId });
            deleteList.push({
              productId: item.prdtId,
              productTitle: item.prdtNm,
              partner: item.patncNm,
            });
          } else if (item.showId === id) {
            showList.push({ showId: item.showId });
          }
        }
      });

      if (deleteList.length > 0) {
        const { productId, productTitle, partner } = deleteList.reduce(
          (acc, item) => {
            acc.productId.push(item.productId);
            acc.productTitle.push(item.productTitle);
            acc.partner.push(item.partner);
            return acc;
          },
          { productId: [], productTitle: [], partner: [] }
        );
        const params = {
          menu: "Favorite",
          productCount: productId.length,
          partnerCount: partner.length,
          contextName: LOG_CONTEXT_NAME.MYPAGE,
          messageId: LOG_MESSAGE_ID.MYPAGE_DELETE,
        };

        dispatch(sendLogTotalRecommend(params));
      }
      if (productList.length > 0 || showList.length > 0) {
        dispatch(deleteMyFavorite({ productList, showList }));
        dispatch(
          sendLogMyPageMyDelete({
            cnt: `${productList.length + showList.length}`,
          })
        );
      }
    }
    setActiveDelete((prev) => !prev);
  }, [dispatch, favoritesDatas, selectedItems, activeDelete]);

  const handleSelectAllToggle = useCallback(() => {
    const newState = !selectAll;

    setSelectedItems(
      Object.keys(selectedItems).reduce((acc, key) => {
        acc[key] = newState;

        return acc;
      }, {})
    );

    setSelectAll(newState);
  }, [selectAll, selectedItems]);

  const handlePreviousButtonClick = useCallback(() => {
    dispatch(popPanel());
  }, [dispatch]);

  const handleCancelButtonClick = useCallback(() => {
    setActiveDelete(false);
    setTimeout(() => {
      Spotlight.focus("favorites_header");
    }, 0);
    const initialSelectedItems = favoritesDatas?.reduce((acc, item) => {
      acc[item.prdtId] = false;
      return acc;
    }, {});

    setSelectedItems(initialSelectedItems);
    setSelectAll(false);
  }, [favoritesDatas, activeDelete]);

  const handleItemClick = useCallback(
    (patnrId, prdtId, prdtNm, patncNm, showId, showNm, brndNm) => (ev) => {
      const params = {
        menu: "Favorite",
        productId: prdtId,
        productTitle: prdtNm,
        partner: patncNm,
        showId: showId,
        showTitle: showNm,
        brand: brndNm,
        contextName: LOG_CONTEXT_NAME.MYPAGE,
        messageId: LOG_MESSAGE_ID.MYPAGE_CLICK,
      };
      dispatch(sendLogTotalRecommend(params));

      const target = ev.currentTarget;
      let currentSpotId = null;

      if (target) {
        currentSpotId = target.getAttribute("data-spotlight-id");

        dispatch(
          updatePanel({
            name: panel_names.MY_PAGE_PANEL,
            panelInfo: {
              currentSpot: currentSpotId,
              focusedContainerId: focusedContainerIdRef.current,
            },
          })
        );
      }

      dispatch(
        pushPanel({
          name: panel_names.DETAIL_PANEL,
          panelInfo: { patnrId: patnrId, prdtId: prdtId },
        })
      );
    },
    []
  );

  const handleItemToggle = useCallback(
    (prdtId) => () => {
      setSelectedItems((prev) => ({ ...prev, [prdtId]: !prev[prdtId] }));
      setSelectAll(
        Object.values({
          ...selectedItems,
          [prdtId]: !selectedItems[prdtId],
        }).every(Boolean)
      );
    },
    [selectedItems]
  );
  const onFocusedContainerId = useCallback((containerId) => {
    focusedContainerIdRef.current = containerId;
  }, []);
  return (
    <>
      <THeader
        spotlightId="favorites_header"
        title={title}
        className={css.favoritesHeader}
        ariaLabel="FAVORITE, heading 1"
      >
        <HeaderButtonContainer className={css.headerButtonContainer}>
          {activeDelete && (
            <>
              <div className={css.deleteAll}>
                <TCheckBox
                  selected={selectAll}
                  onToggle={handleSelectAllToggle}
                />
                <p className={css.deleteText}>{$L("All")}</p>
              </div>
              <TButton
                type={TYPES.mypage}
                className={css.cancelBtn}
                onClick={handleCancelButtonClick}
                ariaLabel="Cancel"
              >
                {$L("Cancel")}
              </TButton>
            </>
          )}
          {favoritesDatas && favoritesDatas.length > 0 ? (
            <TButton
              type={TYPES.mypage}
              className={css.deleteBtn}
              onClick={handleDeleteBtnClick}
              ariaLabel="Delete"
            >
              {$L("Delete")}
            </TButton>
          ) : null}
        </HeaderButtonContainer>
      </THeader>

      <TBody scrollable={false} spotlightDisabled={!isOnTop}>
        {!loading && favoritesDatas && favoritesDatas.length > 0 && (
          <TVerticalPagenator
            className={css.favoritesContentsWrap}
            spotlightId={"favorites_verticalPagenator"}
            defaultContainerId={panelInfo?.focusedContainerId}
            disabled={!isOnTop}
            onFocusedContainerId={onFocusedContainerId}
            cbChangePageRef={cbChangePageRef}
            topMargin={18}
          >
            <ContainerBasic
              className={css.container}
              spotlightId={SpotlightIds.MY_PAGE_FAVORITES_BOX}
            >
              {favoritesDatas.map((item, index) => {
                return (
                  <MyPageItemCard
                    key={index}
                    spotlightId={`${item.prdtId}-${item.patnrId}`}
                    thumbnail={item.imgUrl}
                    title={item.prdtNm}
                    soldOutYn={item.soldOutYn}
                    activeDelete={activeDelete}
                    selected={selectedItems[item.prdtId]}
                    onClick={handleItemClick(
                      item.patnrId,
                      item.prdtId,
                      item.prdtNm,
                      item.patncNm
                    )}
                    onToggle={handleItemToggle(item.prdtId)}
                    length={favoritesDatas.length}
                    index={index}
                    dataWheelPoint={true}
                  />
                );
              })}
            </ContainerBasic>
          </TVerticalPagenator>
        )}
        {!loading && favoritesDatas && favoritesDatas.length <= 0 && (
          <div className={css.noDataWrap}>
            <h1 className={css.noDataTitle} aria-label="You have no Favorites">
              {$L("No favorites yet")}
            </h1>
            <TButton
              type={TYPES.mypage}
              className={css.backBtn}
              onClick={handlePreviousButtonClick}
              spotlightId={"mypage-favorites-nodata"}
            >
              {$L("Back")}
            </TButton>
          </div>
        )}
      </TBody>
    </>
  );
}
