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 { setHidePopup, setShowPopup } from "../../../../actions/commonActions";
import {
  sendLogMyPageAlertFlag,
  sendLogMyPageMyDelete,
  sendLogTotalRecommend,
} from "../../../../actions/logActions";
import {
  deleteMyUpcomingAlertShow,
  getMyUpcomingAlertShow,
  setMyUpcomingUseAlert,
} from "../../../../actions/myPageActions";
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 TPopUp from "../../../../components/TPopUp/TPopUp";
import TSwitch from "../../../../components/TSwitch/TSwitch";
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import * as Config from "../../../../utils/Config";
import { $L } from "../../../../utils/helperMethods";
import { SpotlightIds } from "../../../../utils/SpotlightIds";
import css from "./Reminders.module.less";
import RemindersCard, { SIZES } from "./RemindersCard";

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

export default function Reminders({ title, cbScrollTo }) {
  const dispatch = useDispatch();

  const { upComingAlertShow } = useSelector(
    (state) => state.myPage.upComingData
  );
  const { popupVisible, activePopup } = useSelector(
    (state) => state.common.popup
  );

  const [useAlarm, setUseAlarm] = useState(
    upComingAlertShow?.upcomAlamUseFlag === "Y"
  );

  const [activeDelete, setActiveDelete] = useState(false);
  const [selectedItems, setSelectedItems] = useState({});
  const [selectAll, setSelectAll] = useState(false);

  const focusTimerRef = useRef();
  const alertShowTimer = useRef(null);

  useEffect(() => {
    if (upComingAlertShow && Object.keys(upComingAlertShow).length > 0) {
      const alertShowsArray = upComingAlertShow?.alertShows;
      const alertShowsLength = upComingAlertShow?.alertShows.length;

      if (alertShowsArray) {
        const focusTarget =
          alertShowsLength > 0
            ? SpotlightIds.MY_PAGE_REMINDRES_BOX
            : "mypage-reminder-checkbox";

        focusTimerRef.current = setTimeout(() => Spotlight.focus(focusTarget));
      }
    }
  }, [upComingAlertShow]);

  useEffect(() => {
    setUseAlarm(upComingAlertShow?.upcomAlamUseFlag === "Y");
  }, [upComingAlertShow?.upcomAlamUseFlag]);

  useEffect(() => {
    const initialSelectedItems = {};
    upComingAlertShow.alertShows?.forEach((item) => {
      initialSelectedItems[item.showId] = false;
    });
    setSelectedItems(initialSelectedItems);
  }, [upComingAlertShow]);

  useEffect(() => {
    const removeOldItems = () => {
      let showList = [];

      if (
        upComingAlertShow?.alertShows &&
        upComingAlertShow.alertShows.length > 0
      ) {
        const currentDate = new Date();

        for (let i = 0; i < upComingAlertShow.alertShows.length; i++) {
          const regDate = new Date(upComingAlertShow.alertShows[i].regDt);
          const daysDifference = Math.floor(
            (regDate - currentDate) / (1000 * 60 * 60 * 24)
          );

          if (daysDifference >= 30) {
            showList.push({
              patnrId: upComingAlertShow.alertShows[i].patnrId,
              showId: upComingAlertShow.alertShows[i].showId,
            });
          }
        }
      }

      if (showList.length > 0) {
        dispatch(deleteMyUpcomingAlertShow({ showList }));
        dispatch(getMyUpcomingAlertShow());
      }
    };

    removeOldItems();
  }, [dispatch, upComingAlertShow]);

  useEffect(() => {
    return () => {
      clearTimeout(focusTimerRef.current);
      clearTimeout(alertShowTimer.current);
    };
  }, []);

  const handleToggleSwitchButton = useCallback(() => {
    const flag = useAlarm ? "N" : "Y";

    if (flag === "N") {
      dispatch(setShowPopup(Config.ACTIVE_POPUP.alarmOffPopup));
    }
    if (flag === "Y") {
      dispatch(setShowPopup(Config.ACTIVE_POPUP.alarmOnPopup));
    }

    dispatch(setMyUpcomingUseAlert({ upcomingAlamUseFlag: flag }));
    setUseAlarm(!useAlarm);
    dispatch(
      sendLogTotalRecommend({
        status: flag === "N" ? "Off" : "On",
        contextName: Config.LOG_CONTEXT_NAME.REMINDERS,
        messageId: Config.LOG_MESSAGE_ID.TOGGLE_CLICK,
      })
    );
    dispatch(
      sendLogMyPageAlertFlag({
        alertFlag: flag === "N" ? "Off" : "On",
      })
    );
  }, [dispatch, useAlarm]);

  const handleDeleteBtnClick = useCallback(() => {
    if (activeDelete) {
      const updatedSelectedItems = {};
      let showList = [];
      let deletedList = [];

      Object.keys(selectedItems).forEach((id) => {
        updatedSelectedItems[id] = false;

        if (selectedItems[id]) {
          const foundItem = upComingAlertShow.alertShows.find(
            (item) => item.patnrId === id || item.showId === id
          );

          if (
            foundItem &&
            (foundItem.showId === id || foundItem.patnrId === id)
          ) {
            showList.push({
              patnrId: foundItem.patnrId,
              showId: foundItem.showId,
            });
          }
          deletedList.push({
            partner: foundItem.patncNm,
            contentTitle: foundItem.showNm,
            contentId: foundItem.showId,
          });
        }
      });
      if (deletedList.length > 0) {
        const { contentId, contentTitle, partner } = deletedList.reduce(
          (acc, item) => {
            acc.contentId.push(item.contentId);
            acc.contentTitle.push(item.contentTitle);
            acc.partner.push(item.partner);
            return acc;
          },
          { contentId: [], contentTitle: [], partner: [] }
        );

        const params = {
          menu: "Reminders",
          showCount: contentId.length,
          partnerCount: partner.length,
          contextName: Config.LOG_CONTEXT_NAME.MYPAGE,
          messageId: Config.LOG_MESSAGE_ID.MYPAGE_DELETE,
        };

        dispatch(sendLogTotalRecommend(params));
      }

      setSelectedItems(updatedSelectedItems);
      setSelectAll(false);

      if (showList.length > 0) {
        dispatch(deleteMyUpcomingAlertShow({ showList }));

        alertShowTimer.current = setTimeout(() => {
          dispatch(getMyUpcomingAlertShow());
          dispatch(sendLogMyPageMyDelete({ cnt: `${showList.length}` }));
        }, 200);
      }
    }

    setActiveDelete((prev) => !prev);
  }, [dispatch, upComingAlertShow, 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 handleItemToggle = useCallback(
    (showId) => () => {
      setSelectedItems((prev) => ({ ...prev, [showId]: !prev[showId] }));
      setSelectAll(
        Object.values({
          ...selectedItems,
          [showId]: !selectedItems[showId],
        }).every(Boolean)
      );
    },
    [selectedItems]
  );

  const handleCancel = useCallback(() => {
    dispatch(setHidePopup());
    focusTimerRef.current = setTimeout(
      () => Spotlight.focus("mypage-reminder-checkbox"),
      0
    );
  }, [dispatch]);

  const handleCancelButtonClick = useCallback(() => {
    setActiveDelete(false);

    const initialSelectedItems = upComingAlertShow.alertShows?.reduce(
      (acc, item) => {
        acc[item.showId] = false;
        return acc;
      },
      {}
    );

    setSelectedItems(initialSelectedItems);
    setSelectAll(false);
    Spotlight.focus("mypage-reminder-delete");
  }, [upComingAlertShow]);

  const renderItem = useCallback(
    ({ index, ...rest }) => {
      const sortedAlertShows = upComingAlertShow.alertShows
        .slice()
        .sort((a, b) => new Date(a.strtDt) - new Date(b.strtDt));

      const listItem = sortedAlertShows[index];

      return (
        <RemindersCard
          {...rest}
          key={listItem.patnrId + listItem.showId}
          alamDispFlag={listItem.alamDispFlag}
          chanId={listItem.chanId}
          dfltThumbnailImgPath={listItem.dfltThumbnailImgPath}
          endDt={listItem.endDt}
          hstNm={listItem.hstNm}
          lgCatCd={listItem.lgCatCd}
          lgCatNm={listItem.lgCatNm}
          patncLogoPath={listItem.patncLogoPath}
          patncNm={listItem.patncNm}
          patnrId={listItem.patnrId}
          regDt={listItem.regDt}
          showId={listItem.showId}
          showNm={listItem.showNm}
          strtDt={listItem.strtDt}
          thumbnailUrl={listItem.thumbnailUrl}
          activeDelete={activeDelete}
          selected={selectedItems[listItem.showId]}
          onToggle={handleItemToggle(listItem.showId)}
          index={index}
          length={upComingAlertShow.alertShows.length}
        />
      );
    },
    [upComingAlertShow, activeDelete, selectedItems, handleItemToggle]
  );

  return (
    <>
      <THeader
        title={title}
        className={css.tHeader}
        ariaLabel={title + ", heading 1"}
      >
        <TSwitch
          selected={useAlarm}
          onClick={handleToggleSwitchButton}
          spotlightId="mypage-reminder-checkbox"
        />

        <HeaderButtonContainer className={css.headerButtonContainer}>
          {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>
            </>
          )}

          {upComingAlertShow.alertShows &&
          upComingAlertShow.alertShows.length > 0 ? (
            <TButton
              type={TYPES.mypage}
              className={css.deleteBtn}
              onClick={handleDeleteBtnClick}
              ariaLabel="Delete"
              spotlightId="mypage-reminder-delete"
            >
              {$L("Delete")}
            </TButton>
          ) : null}
        </HeaderButtonContainer>
      </THeader>

      <TBody cbScrollTo={cbScrollTo} className={css.tBody}>
        <div className={css.remindersContentsWrap}>
          {upComingAlertShow &&
          upComingAlertShow.alertShows &&
          upComingAlertShow.alertShows.length > 0 ? (
            <TVirtualGridList
              spotlightId={SpotlightIds.MY_PAGE_REMINDRES_BOX}
              className={css.grid}
              itemRenderer={renderItem}
              dataSize={upComingAlertShow.alertShows.length}
              itemWidth={SIZES.itemWidth}
              itemHeight={SIZES.itemHeight}
              spacing={SIZES.spacing}
            />
          ) : (
            <div className={css.noDataWrap}>
              <h1 className={css.noDataTitle} aria-label="You have no Alerts">
                {$L("No Alerts Yet")}
              </h1>
            </div>
          )}
        </div>
      </TBody>

      {activePopup === Config.ACTIVE_POPUP.alarmOffPopup && (
        <TPopUp
          kind="textPopup"
          open={popupVisible}
          hasButton
          button1Text={$L("OK")}
          hasText
          text={
            <div
              aria-label="Reminder Notification turned ‘OFF’"
              dangerouslySetInnerHTML={{
                __html: `${$L("Reminder Notification turned OFF")}`,
              }}
            />
          }
          onClose={handleCancel}
        />
      )}

      {activePopup === Config.ACTIVE_POPUP.alarmOnPopup && (
        <TPopUp
          kind="textPopup"
          open={popupVisible}
          hasButton
          button1Text={$L("OK")}
          hasText
          text={
            <div
              aria-label="Reminder Notification turned ‘ON’"
              dangerouslySetInnerHTML={{
                __html: `${$L("Reminder Notification turned ON")}`,
              }}
            />
          }
          onClose={handleCancel}
        />
      )}
    </>
  );
}
