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

// hooks
import { useMobileWidth } from "../../hooks/useMobileWidth";
import useDateFormatting from "../../hooks/useDateFormatting";

// components
import { AccountSummary } from "../AccountSummary";
import { Button } from "../Button";
import { Table } from "../Table";
import { Visual } from "../Visual";

// svgs
import {
  AddSquareIcon,
  ReferralPattern,
  StickyNoteIcon,
} from "../../assets/svgs";

// styles
import { Footer } from "../Footer";
import { Link } from "react-router-dom";

import "../../assets/css/main-theme.css";
import "./Staking.css";
import DropDownSvg from "../../assets/svgs/DropDownSvg";

export const Staking = ({
  accountSummaryData,
  walletBalance,
  tableHead,
  stakersRecord,
  loading,
  stackContractInfo,
  handlePopUpOpen,
  tableEmptyData,
  isFetching,
  hasMoreData,
  infiniteScrollRef,
  unstakeLoading,
  harvestLoading,
  isActive,
  currencyStakes = [],
  currencyStakesLoading,
  currencyStakesTableHead,
  apyPercent,
  translates,
  helpSupportClick,
}) => {
  const [mobileExpand, setMobileExpand] = useState(null);
  const [buttonLoading, setButtonLoading] = useState(null);
  const { width, mobile } = useMobileWidth();

  const [selectedTab, setSelectedTab] = useState("staking");
  const { convertDateFormat, convertReceivedDateFormat } = useDateFormatting();

  // Utility functions to calculate rewards
  const calculateCurrentReward = (amount, apy, startDate) => {
    const now = new Date();
    const stakingPeriodInSeconds =
      (now.getTime() - new Date(startDate).getTime()) / 1000;
    const annualReward = amount * (apy / 100);
    return (annualReward / (365 * 24 * 60 * 60)) * stakingPeriodInSeconds;
  };

  const calculateTotalReward = (amount, apy, startDate, endDate) => {
    const stakingPeriodInSeconds =
      (new Date(endDate).getTime() - new Date(startDate).getTime()) / 1000;
    const annualReward = amount * (apy / 100);
    return (annualReward / (365 * 24 * 60 * 60)) * stakingPeriodInSeconds;
  };

  let tableData = null;
  const calculateRemainingDays = (unstakeDate) => {
    const today = new Date();
    const endDate = new Date(convertDateFormat(unstakeDate));
    const timeDiff = endDate - today;
    const days = Math.ceil(timeDiff / (1000 * 60 * 60 * 24));
    if (0 < days) {
      return days;
    } else {
      return 0;
    }
  };

  const calculateAPY = (amount, rewards, staketime, unstakeTime) => {
    let timeDifference = unstakeTime.getTime() - staketime.getTime();
    let days = Math.ceil(timeDifference / (1000 * 60 * 60 * 24));
    const yearlyRewards = (Number(rewards) * 365) / days;
    const apy = (yearlyRewards / Number(amount)) * 100;
    return apy.toFixed(2);
  };

  if (selectedTab === "staking") {
    tableData = stakersRecord.slice().map((item, index) => {
      if (item.unstaked) return false;
      const createdAt = new Date(convertDateFormat(item?.staketime));
      const createdUn = new Date(convertDateFormat(item?.unstaketime));
      const createdTime = createdAt.toLocaleString("en-US", {
        month: "short",
        day: "numeric",
        year: "numeric",
      });
      const createdUnTime = createdUn.toLocaleString("en-US", {
        month: "short",
        day: "numeric",
        year: "numeric",
      });
      const remainingDays = calculateRemainingDays(item?.unstaketime);
      const apy = calculateAPY(
        item?.amount,
        item?.realtimeRewardPerBlock,
        createdAt,
        createdUn
      );
      return (
        <div
          className={`table-parent ${mobileExpand === index ? "active" : ""}`}
          key={index}
        >
          <div
            className={"table"}
            style={{
              width: width < 1300 ? "calc(100% - 50px)" : "calc(100% - 222px)",
              cursor: "pointer",
            }}
          >
            {tableHead?.slice(0, 6).map((i, index) => {
              return (
                <div
                  key={index}
                  className={`td col ${i.mobileWidth ? true : false}`}
                  style={{ width: `${mobile ? i.mobileWidth : i.width}%` }}
                >
                  <span>
                    {
                      [
                        item?.amount?.toLocaleString("en-US", {
                          minimumFractionDigits: 2,
                          maximumFractionDigits: 2,
                        }) + " AONE",
                        remainingDays + " Days",
                        parseFloat(item.realtimeRewardPerBlock).toFixed(2) +
                          " AONE",
                        createdTime,
                        createdUnTime,
                        apy + " %",
                      ][index]
                    }
                  </span>
                </div>
              );
            })}
          </div>
          <div className="table-more" />
          {width < 1300 ? (
            <div
              className="icon-place"
              style={{ display: "flex", cursor: "pointer" }}
              onClick={() => {
                mobileExpandFunc(index);
              }}
            >
              <DropDownSvg />
            </div>
          ) : (
            <div className="table-buttons">
              {[6, 7].map((index1) => (
                <div className="td" key={index1}>
                  <Button
                    element="staking-button"
                    label={
                      index1 === 6
                        ? unstakeLoading && buttonLoading === index
                          ? "Loading..."
                          : "Unstake"
                        : harvestLoading && buttonLoading === index
                        ? "Loading..."
                        : "Harvest"
                    }
                    active={index1 === 6}
                    customStyles={{ borderRadius: "32px" }}
                    onClick={() => {
                      handleButtonLoading(index);
                      tableHead[index1]?.onClick(index);
                    }}
                    disabled={
                      !isActive || index1 === 6
                        ? item.unstaked ||
                          Number(item?.[0]) >
                            Math.floor(new Date().getTime() / 1000) ||
                          (buttonLoading === index && unstakeLoading) ||
                          walletBalance < 0
                        : (buttonLoading === index && harvestLoading) ||
                          item.realtimeRewardPerBlock == 0 ||
                          walletBalance < 0
                    }
                  />
                </div>
              ))}
            </div>
          )}
          <div
            className="table-mobile"
            style={{ display: "block", cursor: "initial" }}
          >
            <div className="table-mobile-content">
              {width <= 1300 && (
                <>
                  {[1, 2].map((index) => (
                    <div className="td" key={index}>
                      <div className="mobile-ttl">{tableHead[index]?.name}</div>
                      <span>
                        {index === 1 && item?.staketime}
                        {index === 2 && item?.unstaketime}
                      </span>
                    </div>
                  ))}
                </>
              )}
              {width <= 400 && (
                <>
                  {[2].map((index) => (
                    <div className="td" key={index}>
                      <div className="mobile-ttl">{tableHead[index]?.name}</div>
                      <span>
                        {parseFloat(item?.realtimeRewardPerBlock).toFixed(8)}
                      </span>
                    </div>
                  ))}
                </>
              )}
              <>
                {[3].map((index) => (
                  <div className="td" key={index}>
                    <div className="mobile-ttl">
                      {translates?.earn_reward.en}
                    </div>
                    <span>AONE</span>
                  </div>
                ))}
              </>
              <div className="table-buttons">
                {[6, 7].map((index1) => (
                  <div className="td" key={index1}>
                    <Button
                      element="staking-button"
                      label={
                        index1 === 6
                          ? unstakeLoading && buttonLoading === index
                            ? "Loading..."
                            : "Unstake"
                          : harvestLoading && buttonLoading === index
                          ? "Loading..."
                          : "Harvest"
                      }
                      active={index1 === 6}
                      customStyles={{ borderRadius: "32px" }}
                      onClick={() => {
                        tableHead[index1]?.onClick(index);
                        handleButtonLoading(index);
                      }}
                      disabled={
                        !isActive || index1 === 6
                          ? item.unstaked ||
                            Number(item?.[0]) >
                              Math.floor(new Date().getTime() / 1000) ||
                            unstakeLoading ||
                            walletBalance < 0
                          : harvestLoading ||
                            item.realtimeRewardPerBlock == 0 ||
                            walletBalance < 0
                      }
                    />
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>
      );
    });
  } else {
    tableData = currencyStakes.map((item, index) => {
      if (item.unstaked) return false;
      let unstakeTime = new Date(item?.unstake_time);
      const createdAt = new Date(convertReceivedDateFormat(item?.createdAt));
      const createdUn = new Date(unstakeTime);
      const periodUnformatted = createdUn - createdAt;
      const period = `${parseInt(periodUnformatted / (1000 * 60 * 60 * 24))} D`;
      const currentReward = calculateCurrentReward(
        item?.amount,
        item?.percentage,
        item?.createdAt
      );
      const totalReward = calculateTotalReward(
        item?.amount,
        item?.percentage,
        item?.createdAt,
        item?.unstake_time
      );
      const createdTime = createdAt.toLocaleString("en-US", {
        month: "short",
        day: "numeric",
        year: "numeric",
      });
      const createdUnTime = createdUn.toLocaleString("en-US", {
        month: "short",
        day: "numeric",
        year: "numeric",
      });
      return (
        <div
          className={`table-parent ${mobileExpand === index ? "active" : ""}`}
          key={index}
        >
          <div
            className={"table"}
            style={{
              width: "calc(100% - 50px)",
              cursor: "pointer",
            }}
          >
            {currencyStakesTableHead?.slice(0, 7).map((i, index) => {
              return (
                <div
                  key={index}
                  className={`td col ${i.mobileWidth ? true : false}`}
                  style={{ width: `${mobile ? i.mobileWidth : i.width}%` }}
                >
                  <span>
                    {
                      [
                        `${item?.amount?.toLocaleString("en-US", {
                          minimumFractionDigits: 2,
                          maximumFractionDigits: 8,
                        })} ${item?.currency?.toUpperCase()}`,
                        period,
                        `${item?.percentage.toFixed()} %`,
                        `${item?.expected_reward?.toLocaleString("en-US", {
                          minimumFractionDigits: 2,
                          maximumFractionDigits: 8,
                        })} ${item?.currency?.toUpperCase()}`,
                        currentReward.toFixed(5) +
                          ` ${item?.currency?.toUpperCase()}`,
                        totalReward.toFixed(5) +
                          ` ${item?.currency?.toUpperCase()}`,
                        createdUnTime,
                      ][index]
                    }
                  </span>
                </div>
              );
            })}
          </div>
          <div className="table-more" />
          {width <= 1300 && (
            <div
              className="icon-place"
              style={{ display: "flex", cursor: "pointer" }}
              onClick={() => {
                mobileExpandFunc(index);
              }}
            >
              <DropDownSvg />
            </div>
          )}
          <div
            className="table-mobile"
            style={{ display: "block", cursor: "initial" }}
          >
            <div className="table-mobile-content">
              {width <= 1300 && (
                <>
                  {[1, 2].map((index) => (
                    <div className="td" key={index}>
                      <div className="mobile-ttl">{tableHead[index]?.name}</div>
                      <span>
                        {index === 1 &&
                          new Date(item?.stake_time).toLocaleString("en-US")}
                        {index === 2 &&
                          new Date(item?.unstake_time).toLocaleString("en-US")}
                      </span>
                    </div>
                  ))}
                </>
              )}
              {width <= 400 && (
                <>
                  {[2].map((index) => (
                    <div className="td" key={index}>
                      <div className="mobile-ttl">{tableHead[index]?.name}</div>
                      <span>
                        {parseFloat(item?.realtimeRewardPerBlock).toFixed(8)}
                      </span>
                    </div>
                  ))}
                </>
              )}
            </div>
          </div>
        </div>
      );
    });
  }

  let mobileExpandFunc = (id) => {
    if (id !== mobileExpand) {
      setMobileExpand(id);
    } else {
      setMobileExpand(null);
    }
  };

  useEffect(() => {
    setMobileExpand(null);
    if (width > 1300) {
      setMobileExpand(null);
    }
  }, [selectedTab, width]);

  const handleButtonLoading = (id) => {
    if (buttonLoading !== id) {
      setButtonLoading(id);
    } else {
      setButtonLoading(null);
    }
  };

  return (
    <div className="staking-main">
      <div className="staking-content">
        <div className={"stake-content-main"}>
          <h1 className="main_ttl font-60 colorGold">
            {translates?.staking.en}
          </h1>
          <p className="font-16">{translates?.you_can_stake_and.en}</p>
          <Link
            to={`/staking-details`}
            className="btn btn-primary btn-lg button"
          >
            Staking Details
          </Link>
        </div>
        <AccountSummary data={accountSummaryData} label={"Total Stake"} />
        <div className={"staking-content-main"}>
          <div className="staking_table_top_wrapper">
            <div className="tabsWrap">
              <div
                className={`${selectedTab === "staking" ? "selected" : ""}`}
                onClick={() => setSelectedTab("staking")}
              >
                {translates?.staking.en}
              </div>
              <div
                className={selectedTab === "currency stakes" ? "selected" : ""}
                onClick={() => setSelectedTab("currency stakes")}
              >
                {translates?.currency_staking.en}
              </div>
              <span
                className={`highlight-selected ${
                  selectedTab === "staking"
                    ? "selected-data"
                    : "selected-security"
                }`}
              ></span>
            </div>
            <Button
              element={"referral-button"}
              label={translates?.create_staking.en}
              icon={<AddSquareIcon />}
              onClick={handlePopUpOpen}
            />
          </div>
          <Table
            type={"table-version"}
            tableHead={
              selectedTab === "staking" ? tableHead : currencyStakesTableHead
            }
            mobile={true}
            tableData={
              selectedTab === "stakes" && stakersRecord.length < 1 ? (
                false
              ) : selectedTab === "currency stakes" &&
                currencyStakes.length < 1 ? (
                false
              ) : (
                <>
                  {tableData}
                  {isFetching && (
                    <div
                      className="table-loading-container"
                      style={{ height: "50px" }}
                    >
                      <div
                        className="table-loading"
                        style={{ height: "30px", width: "30px" }}
                      />
                    </div>
                  )}
                  {!isFetching && hasMoreData && (
                    <div style={{ minHeight: "1px" }} ref={infiniteScrollRef} />
                  )}
                </>
              )
            }
            tableEmpty={true}
            tableEmptyData={tableEmptyData}
            loading={
              (selectedTab === "stakes" && loading) ||
              (selectedTab === "currency stakes" && currencyStakesLoading)
            }
            customTableMoreStyles={{
              height: "82px",
              display: "flex",
              width:
                selectedTab === "currency stakes" || width < 1300
                  ? "50px"
                  : "222px",
            }}
            customHeadStyles={{
              width:
                selectedTab === "currency stakes" || width < 1300
                  ? "calc(100% - 50px)"
                  : "calc(100% - 222px)",
            }}
          />
        </div>
      </div>
      <Footer helpSupportClick={helpSupportClick} />
    </div>
  );
};
