import React, { useEffect, useState, useMemo, useCallback } from "react";
import moment from "moment";
import Avatar from "../common/Avatar";
import { convertShortTime } from "../../utils/dateUtils";
import RenderAttendanceStatus from "./RenderAttendanceStatus";
import { useSelector, useDispatch } from "react-redux";
import { fetchAttendanceData } from "../../slices/apiSlice/attedanceLogsSlice";
import DateRangePicker from "../common/DateRangePicker";
import { getCachedData } from "../../slices/apiDataManager";
import eventBus from "../../services/eventBus";

const usePagination = (data, itemsPerPage) => {
  const [currentPage, setCurrentPage] = useState(1);
  const maxPage = Math.ceil(data.length / itemsPerPage);
  const currentItems = useMemo(() => {
    const startIndex = (currentPage - 1) * itemsPerPage;
    const endIndex = startIndex + itemsPerPage;
    return data.slice(startIndex, endIndex);
  }, [data, currentPage, itemsPerPage]);

  const paginate = useCallback((pageNumber) => setCurrentPage(pageNumber), []);
  const resetPage = useCallback(() => setCurrentPage(1), []);

  return {
    currentPage,
    totalPages: maxPage,
    currentItems,
    paginate,
    resetPage,
  };
};

const AttendanceLog = ({
  handleModalData,
  projectId,
  setshowOnlyCheckout,
  showOnlyCheckout,
}) => {
  const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" });
  const dispatch = useDispatch();
  const { data, loading, error } = useSelector((store) => store.attendanceLogs);
  const [isRefreshing, setIsRefreshing] = useState(false);
  const [processedData, setProcessedData] = useState([]);

  const today = new Date();
  today.setHours(0, 0, 0, 0);

  const yesterday = new Date();
  yesterday.setDate(yesterday.getDate() - 1);

  const isSameDay = (dateStr) => {
    if (!dateStr) return false;
    const d = new Date(dateStr);
    d.setHours(0, 0, 0, 0);
    return d.getTime() === today.getTime();
  };

  const isBeforeToday = (dateStr) => {
    if (!dateStr) return false;
    const d = new Date(dateStr);
    d.setHours(0, 0, 0, 0);
    return d.getTime() < today.getTime();
  };

  const sortByName = (a, b) => {
    const nameA = a.firstName.toLowerCase() + a.lastName.toLowerCase();
    const nameB = b.firstName.toLowerCase() + b.lastName.toLowerCase();
    return nameA?.localeCompare(nameB);
  };

  useEffect(() => {
    const { startDate, endDate } = dateRange;
    dispatch(
      fetchAttendanceData({
        projectId,
        fromDate: startDate,
        toDate: endDate,
      })
    );
    setIsRefreshing(false);
  }, [dateRange, projectId, dispatch, isRefreshing]);

  const filtering = (data) => {
    const filteredData = showOnlyCheckout
      ? data.filter((item) => item.checkOutTime === null)
      : data;

    const group1 = filteredData
      .filter((d) => d.activity === 1 && isSameDay(d.checkInTime))
      .sort(sortByName);
    const group2 = filteredData
      .filter((d) => d.activity === 4 && isSameDay(d.checkOutTime))
      .sort(sortByName);
    const group3 = filteredData
      .filter((d) => d.activity === 1 && isBeforeToday(d.checkInTime))
      .sort(sortByName);
    const group4 = filteredData.filter(
      (d) => d.activity === 4 && isBeforeToday(d.checkOutTime)
    );
    const group5 = filteredData
      .filter((d) => d.activity === 2 && isBeforeToday(d.checkOutTime))
      .sort(sortByName);
    const group6 = filteredData
      .filter((d) => d.activity === 5)
      .sort(sortByName);

    const sortedList = [
      ...group1,
      ...group2,
      ...group3,
      ...group4,
      ...group5,
      ...group6,
    ];

    // Group by date
    const groupedByDate = sortedList.reduce((acc, item) => {
      const date = (item.checkInTime || item.checkOutTime)?.split("T")[0];
      if (date) {
        acc[date] = acc[date] || [];
        acc[date].push(item);
      }
      return acc;
    }, {});

    // Sort dates in descending order
    const sortedDates = Object.keys(groupedByDate).sort(
      (a, b) => new Date(b) - new Date(a)
    );

    // Create the final sorted array
    const finalData = sortedDates.flatMap((date) => groupedByDate[date]);
    setProcessedData(finalData);
  }

  useEffect(() => {
    filtering(data)
  }, [data, showOnlyCheckout]);

  const {
    currentPage,
    totalPages,
    currentItems: paginatedAttendances,
    paginate,
    resetPage,
  } = usePagination(processedData, 20);

  // Reset to the first page whenever processedData changes (due to switch on/off)
  useEffect(() => {
    resetPage();
  }, [processedData, resetPage]);

  const handler = useCallback(
  (msg) => {
    const { startDate, endDate } = dateRange;
    const checkIn = msg.response.checkInTime.substring(0, 10);
    if (
      projectId === msg.projectId &&
      startDate <= checkIn &&
      checkIn <= endDate
    ) {
      const updatedAttendance = data.map((item) =>
        item.id === msg.response.id
          ? { ...item, ...msg.response }
          : item
      );

      filtering(updatedAttendance);
      resetPage();
    }
  },
  [projectId, dateRange, data, filtering, resetPage]
);

    useEffect(() => {
    eventBus.on("attendance_log", handler);
    return () => eventBus.off("attendance_log", handler);
  }, [handler]);

  return (
    <>
      <div
        className="dataTables_length text-start py-2 d-flex justify-content-between"
        id="DataTables_Table_0_length"
      >
        <div className="d-flex align-items-center my-0 ">
          <DateRangePicker
            onRangeChange={setDateRange}
            defaultStartDate={yesterday}
          />
          <div className="form-check form-switch text-start m-0 ms-5">
            <input
              type="checkbox"
              className="form-check-input"
              role="switch"
              id="inactiveEmployeesCheckbox"
              checked={showOnlyCheckout}
              onChange={(e) => setshowOnlyCheckout(e.target.checked)}
            />
            <label className="form-check-label ms-0">Show Pending</label>
          </div>
        </div>
        <div className="col-md-2 m-0 text-end">
          <i
            className={`bx bx-refresh cursor-pointer fs-4 ${
              loading || isRefreshing ? "spin" : ""
            }`}
            title="Refresh"
            onClick={() => setIsRefreshing(true)}
          />
        </div>
      </div>
      <div
        className="table-responsive text-nowrap"
        style={{ minHeight: "250px" }}
      >
        {data && data.length > 0 && (
          <table className="table mb-0">
            <thead>
              <tr>
                <th className="border-top-1" colSpan={2}>
                  Name
                </th>
                <th className="border-top-1">Date</th>
                <th>
                  <i className="bx bxs-down-arrow-alt text-success"></i>{" "}
                  Check-In
                </th>
                <th>
                  <i className="bx bxs-up-arrow-alt text-danger"></i> Check-Out
                </th>
                <th>Action</th>
              </tr>
            </thead>
            <tbody>
              {(loading || isRefreshing) && (
                <tr>
                  <td colSpan={6}>Loading...</td>
                </tr>
              )}
              {!loading &&
                !isRefreshing &&
                paginatedAttendances.reduce((acc, attendance, index, arr) => {
                  const currentDate = moment(
                    attendance.checkInTime || attendance.checkOutTime
                  ).format("YYYY-MM-DD");
                  const previousAttendance = arr[index - 1];
                  const previousDate = previousAttendance
                    ? moment(
                        previousAttendance.checkInTime ||
                          previousAttendance.checkOutTime
                      ).format("YYYY-MM-DD")
                    : null;

                  if (!previousDate || currentDate !== previousDate) {
                    acc.push(
                      <tr
                        key={`header-${currentDate}`}
                        className="table-row-header"
                      >
                        <td colSpan={6} className="text-start">
                          <strong>
                            {moment(currentDate).format("DD-MM-YYYY")}
                          </strong>
                        </td>
                      </tr>
                    );
                  }
                  acc.push(
                    <tr key={index}>
                      <td colSpan={2}>
                        <div className="d-flex justify-content-start align-items-center">
                          <Avatar
                            firstName={attendance.firstName}
                            lastName={attendance.lastName}
                          />
                          <div className="d-flex flex-column">
                            <a href="#" className="text-heading text-truncate">
                              <span className="fw-normal">
                                {attendance.firstName} {attendance.lastName}
                              </span>
                            </a>
                          </div>
                        </div>
                      </td>
                      <td>
                        {moment(
                          attendance.checkInTime || attendance.checkOutTime
                        ).format("DD-MMM-YYYY")}
                      </td>
                      <td>{convertShortTime(attendance.checkInTime)}</td>
                      <td>
                        {attendance.checkOutTime
                          ? convertShortTime(attendance.checkOutTime)
                          : "--"}
                      </td>
                      <td className="text-center">
                        <RenderAttendanceStatus
                          attendanceData={attendance}
                          handleModalData={handleModalData}
                          Tab={2}
                          currentDate={today.toLocaleDateString("en-CA")}
                        />
                      </td>
                    </tr>
                  );
                  return acc;
                }, [])}
            </tbody>
          </table>
        )}
        {!loading && !isRefreshing && data.length === 0 && (
          <span>No employee logs</span>
        )}
        {error && !loading && !isRefreshing && (
          <tr>
            <td colSpan={6}>{error}</td>
          </tr>
        )}
      </div>
      {!loading && !isRefreshing && processedData.length > 10 && (
        <nav aria-label="Page ">
          <ul className="pagination pagination-sm justify-content-end py-1">
            <li className={`page-item ${currentPage === 1 ? "disabled" : ""}`}>
              <button
                className="page-link btn-xs"
                onClick={() => paginate(currentPage - 1)}
              >
                &laquo;
              </button>
            </li>
            {Array.from({ length: totalPages }, (_, i) => i + 1).map(
              (pageNumber) => (
                <li
                  key={pageNumber}
                  className={`page-item ${
                    currentPage === pageNumber ? "active" : ""
                  }`}
                >
                  <button
                    className="page-link"
                    onClick={() => paginate(pageNumber)}
                  >
                    {pageNumber}
                  </button>
                </li>
              )
            )}
            <li
              className={`page-item ${
                currentPage === totalPages ? "disabled" : ""
              }`}
            >
              <button
                className="page-link"
                onClick={() => paginate(currentPage + 1)}
              >
                &raquo;
              </button>
            </li>
          </ul>
        </nav>
      )}
    </>
  );
};

export default AttendanceLog;
