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

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

import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";

import {
  changeAppStatus,
  changeLocalSettings,
} from "../../../../actions/commonActions";
import {
  sendLogMyPageMyDelete,
  sendLogTotalRecommend,
} from "../../../../actions/logActions";
import {
  clearRecentlyViewedInfo,
  getMyRecentlyViewedInfo,
} from "../../../../actions/myPageActions";
import { popPanel } 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 { $L } from "../../../../utils/helperMethods";
import { SpotlightIds } from "../../../../utils/SpotlightIds";
import css from "../RecentlyViewed/RecentlyViewed.module.less";
import RecentlyViewedContents from "./RecentlyViewedContents";
import { LOG_CONTEXT_NAME, LOG_MESSAGE_ID } from "../../../../utils/Config";

const HeaderButtonContainer = SpotlightContainerDecorator(
  { enterTo: "last-focused" },
  "div"
);

export default function RecentlyViewed({ title, panelInfo, isOnTop }) {
  const [activeDelete, setActiveDelete] = useState(false);
  const [selectedItems, setSelectedItems] = useState({});
  const [selectAll, setSelectAll] = useState(false);
  const [selectedPatnrId, setSelectedPatnrId] = useState();
  const [recentlyDatas, setRecentlyDatas] = useState([]);
  const [loading, setLoading] = useState(true);
  const cbChangePageRef = useRef(null);
  const dispatch = useDispatch();

  const recentlydataInfo = useSelector(
    (state) => state.myPage.recentlyViewedData
  );
  const recentlyProductsData = useSelector(
    (state) => state.myPage.recentlyViewedData?.data?.recentlyProducts
  );
  const recentlyShowData = useSelector(
    (state) => state.myPage.recentlyViewedData?.data?.recentlyShows
  );
  const recentlyViewedSuccess = useSelector(
    (state) => state.myPage?.recentlyViewedSuccess
  );
  const localRecentItems = useSelector(
    (state) => state.localSettings?.recentItems
  );

  const { httpHeader } = useSelector((state) => state.common);

  useEffect(() => {
    if (recentlyDatas) {
      setTimeout(() => {
        const tHeader = document.querySelector(
          `[data-spotlight-id="recentlyviewed_header"]`
        );
        const tBody = document.querySelector(`[id="${SpotlightIds.TBODY}"]`);

        if (isOnTop) {
          if (cbChangePageRef.current) {
            cbChangePageRef.current(0, false);

            if (tHeader && tBody) {
              const focusTarget = activeDelete ? tHeader : tBody;
              Spotlight.focus(focusTarget);
            }
          }
        }
      });
    }
  }, [isOnTop, recentlyDatas]);

  useEffect(() => {
    if (panelInfo) {
      if (cbChangePageRef.current) {
        cbChangePageRef.current(0, true);
      }
      setSelectedPatnrId(panelInfo);
    }
  }, [panelInfo]);

  useEffect(() => {
    // selectedItems 초기화 작업
    const initialSelectedItems = recentlyDatas?.reduce((acc, currVal) => {
      currVal.productInfos.map((item) => {
        if (item.prdtId) {
          acc[item.prdtId] = false;
        } else if (item.showId) {
          acc[item.showId] = false;
        }
      });
      return acc;
    }, {});
    setSelectedItems(initialSelectedItems);
  }, [activeDelete]);

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

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

  const handleDeleteBtnClick = useCallback(() => {
    if (activeDelete) {
      let recentItems = [...localRecentItems];
      if (!Object.values(selectedItems).includes(true)) {
        setActiveDelete(false);
        return;
      }

      const updatedRecentItems = localRecentItems.filter((item) => {
        const id = item.prdtId || item.showId;

        return !selectedItems[id];
      });

      dispatch(changeLocalSettings({ recentItems: updatedRecentItems }));

      const updatedRecentlyDatas = recentlyDatas.reduce((acc, data) => {
        const updatedProductInfos = data.productInfos.filter((item) => {
          const id = item.prdtId || item.showId;

          return !selectedItems[id];
        });

        if (updatedProductInfos.length > 0) {
          acc.push({ ...data, productInfos: updatedProductInfos });
        }

        return acc;
      }, []);

      setRecentlyDatas(updatedRecentlyDatas);

      const deletedCount = Object.values(selectedItems).filter(Boolean).length;

      if (deletedCount > 0) {
        dispatch(
          sendLogMyPageMyDelete({
            cnt: `${deletedCount}`,
          })
        );
      }
      // delete 버튼 클릭 시 삭제된 데이터 출력
      recentlyDatas.reduce((acc, data) => {
        const deleteProductInfo = data.productInfos.filter((item) => {
          const id = item.prdtId;
          return selectedItems[id];
        });
        const deleteShowInfo = data.productInfos.filter((item) => {
          const id = item.showId;
          return selectedItems[id];
        });
     
        // 공통 로그 전송 함수
        const sendDeleteLog = (items, type) => {
          if (items.length === 0) return;
          
          const params = {
            menu: "Recently Viewed",
            partnerCount: items.length,
            contextName: LOG_CONTEXT_NAME.MYPAGE,
            messageId: LOG_MESSAGE_ID.MYPAGE_DELETE,
          };

          if (type === 'product') {
            const { productId, productTitle, partner } = items.reduce(
              (result, item) => {
                result.productId.push(item.prdtId);
                result.productTitle.push(item.prdtNm);
                result.partner.push(item.patncNm);
                return result;
              },
              { productId: [], productTitle: [], partner: [] }
            );
            params.productCount = productId.length;
          } else if (type === 'show') {
            const { showId, showTitle, partner } = items.reduce(
              (result, item) => {
                result.showId.push(item.showId);
                result.showTitle.push(item.showNm);
                result.partner.push(item.patncNm);
                return result;
              },
              { showId: [], showTitle: [], partner: [] }
            );
            params.showCount = showId.length;
          }

          dispatch(sendLogTotalRecommend(params));
        };

        // 제품 정보 로그 전송
        sendDeleteLog(deleteProductInfo, 'product');
        
        // 쇼 정보 로그 전송
        sendDeleteLog(deleteShowInfo, 'show');

        return acc;
      }, []);
      groupByDate();
    }

    setActiveDelete((prev) => !prev);
  }, [
    recentlyDatas,
    selectedItems,
    activeDelete,
    localRecentItems,
    dispatch,
    groupByDate,
  ]);

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

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

        return acc;
      }, {})
    );

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

  const handleItemToggle = useCallback(
    (prdtId) => {
      setSelectedItems((prev) => ({ ...prev, [prdtId]: !prev[prdtId] }));
      setSelectAll(
        Object.values({
          ...selectedItems,
          [prdtId]: !selectedItems[prdtId],
        }).every(Boolean)
      );
    },
    [selectedItems]
  );

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

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

  const groupByDate = useCallback(() => {
    dispatch(
      changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })
    );
    let productListData = [];
    let showListData = [];

    if (localRecentItems && localRecentItems.length > 0) {
      localRecentItems.map((item) => {
        const { cntryCd, patnrId, prdtId, showId } = item;
        if (item.prdtId) {
          productListData.push({ cntryCd, patnrId, prdtId });
        } else if (item.showId) {
          showListData.push({ cntryCd, patnrId, showId });
        }
      });

      dispatch(
        getMyRecentlyViewedInfo({
          showList: showListData,
          productList: productListData,
        })
      );
    } else {
      setLoading(false);
      dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
    }
  }, [dispatch, localRecentItems]);

  useEffect(() => {
    if (
      (recentlyProductsData?.length > 0 || recentlyShowData?.length > 0) &&
      recentlydataInfo?.retCode === 0
    ) {
      const currentTime = new Date().getTime();
      const groupedItems = {};
      let newMakeArray = [];

      if (localRecentItems && localRecentItems.length > 0) {
        localRecentItems.forEach((item) => {
          const { date, prdtId, expireTime, showId } = item;

          if (expireTime > currentTime) {
            newMakeArray.push(item);
          } else return;

          const productInfo = prdtId
            ? recentlyProductsData.find((product) => product.prdtId === prdtId)
            : recentlyShowData.find((product) => product.showId === showId);

          if (productInfo) {
            if (!groupedItems[date]) {
              groupedItems[date] = {
                date: date,
                productInfos: [],
              };
            }
            const existingProductIndex = groupedItems[
              date
            ].productInfos.findIndex((existingProduct) => {
              if (existingProduct.prdtId) {
                return existingProduct.prdtId === prdtId;
              } else {
                return existingProduct.showId === showId;
              }
            });
            if (existingProductIndex !== -1) {
              groupedItems[date].productInfos.splice(existingProductIndex, 1);
            }
            groupedItems[date].productInfos.unshift(productInfo);
          }
        });
      }
      const result = Object.values(groupedItems);
      sortedRecentlyDatas(result);

      // 만료 기간이 지난 데이터 삭제 후 로컬 스토리지에 새로운 배열 저장
      setLoading(false);
      dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
    }
  }, [recentlydataInfo, dispatch, localRecentItems]);

  useEffect(() => {
    // 국가 코드 다르면 local data 삭제
    const checkCntryCd = localRecentItems.findIndex((item) => {
      return item.cntryCd !== httpHeader["X-Device-Country"];
    });

    if (checkCntryCd !== -1) {
      dispatch(changeLocalSettings({ recentItems: [] }));
    }
  }, [httpHeader]);

  const sortedRecentlyDatas = useCallback(
    (data) => {
      const sortedDatas = data.slice().sort((a, b) => {
        return new Date(b.date) - new Date(a.date);
      });
      setRecentlyDatas(sortedDatas);
    },
    [recentlyDatas]
  );

  useEffect(() => {
    return () => {
      dispatch(clearRecentlyViewedInfo());
    };
  }, [dispatch]);

  const hasData = useMemo(() => {
    return (
      recentlyViewedSuccess === 0 &&
      (recentlyProductsData || recentlyShowData) &&
      (recentlyProductsData?.length > 0 || recentlyShowData?.length > 0) &&
      recentlyDatas?.length > 0
    );
  }, [
    recentlyViewedSuccess,
    recentlyProductsData,
    recentlyShowData,
    recentlyDatas,
  ]);

  return (
    <>
      <THeader
        spotlightId="recentlyviewed_header"
        title={title}
        className={css.recentlyViewedHeader}
        ariaLabel="RECENTLY VIEWED, heading 1"
      >
        <HeaderButtonContainer
          className={css.headerButtonContainer}
          spotlightDisabled={!isOnTop}
        >
          {activeDelete && (
            <>
              <div className={css.deleteAll}>
                <TCheckBox
                  selected={selectAll}
                  onToggle={handleSelectAllToggle}
                  ariaLabel={
                    selectAll === true ? "Checked, ALL" : "Not checked, ALL"
                  }
                />
                <p className={css.deleteText}>{$L("All")}</p>
              </div>
              <TButton
                type={TYPES.mypage}
                className={css.cancelBtn}
                onClick={handleCancelButtonClick}
                ariaLabel="Cancel"
              >
                {$L("Cancel")}
              </TButton>
            </>
          )}
          {hasData && (
            <TButton
              type={TYPES.mypage}
              className={css.deleteBtn}
              onClick={handleDeleteBtnClick}
              ariaLabel="Delete"
            >
              {$L("Delete")}
            </TButton>
          )}
        </HeaderButtonContainer>
      </THeader>

      <TBody scrollable={false} spotlightDisabled={!isOnTop}>
        <TVerticalPagenator
          className={css.container}
          spotlightId={"recentlyviewed_verticalPagenator"}
          // onScrollStop={onScrollStop}
          cbChangePageRef={cbChangePageRef}
          topMargin={18}
        >
          {!loading &&
            hasData &&
            recentlyDatas.map((recentDataInfoItem, index, array) => {
              return (
                <RecentlyViewedContents
                  title={recentDataInfoItem.date}
                  indexNo={index}
                  className={css.recentCard}
                  dataSize={recentDataInfoItem.productInfos.length}
                  recentDataInfoItem={recentDataInfoItem}
                  key={`${
                    recentDataInfoItem.productInfos.prdtId
                      ? recentDataInfoItem.productInfos.prdtId
                      : recentDataInfoItem.productInfos.showId
                  }-${recentDataInfoItem.productInfos.patnrId}-${index}`}
                  selectedItems={selectedItems}
                  selectedPatnrId={selectedPatnrId}
                  activeDelete={activeDelete}
                  handleItemToggle={handleItemToggle}
                />
              );
            })}
          {!loading && !hasData && (
            <div className={css.noRecentDataWrap}>
              <h1
                className={css.noRecentTitle}
                aria-label="No shows or items recently viewed."
              >
                {$L("No shows or items recently viewed.")}
              </h1>
              <TButton
                className={css.backBtn}
                onClick={handlePreviousButtonClick}
                spotlightId={"mypage-recentlyViewed-nodata"}
                ariaLabel="Previous"
              >
                {$L("Back")}
              </TButton>
            </div>
          )}
        </TVerticalPagenator>
      </TBody>
    </>
  );
}
