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, setAttendanceData } from "../../slices/apiSlice/attedanceLogsSlice";
import DateRangePicker from "../common/DateRangePicker";
import eventBus from "../../services/eventBus";

const usePagination = (data, itemsPerPage) => {
  const [currentPage, setCurrentPage] = useState(1);
  const totalItems = Array.isArray(data) ? data.length : 0;
  const maxPage = Math.ceil(totalItems / itemsPerPage);

  const currentItems = useMemo(() => {
    if (!Array.isArray(data) || data.length === 0) {
      return [];
    }
    const startIndex = (currentPage - 1) * itemsPerPage;
    const endIndex = startIndex + itemsPerPage;
    return data.slice(startIndex, endIndex);
  }, [data, currentPage, itemsPerPage]);

  const paginate = useCallback((pageNumber) => {
    if (pageNumber > 0 && pageNumber <= maxPage) {
      setCurrentPage(pageNumber);
    }
  }, [maxPage]);

  // Ensure resetPage is returned by the hook
  const resetPage = useCallback(() => setCurrentPage(1), []);

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

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

  const today = useMemo(() => {
    const d = new Date();
    d.setHours(0, 0, 0, 0);
    return d;
  }, []);

  const yesterday = useMemo(() => {
    const d = new Date();
    d.setDate(d.getDate() - 1);
    return d;
  }, []);

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

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

  const sortByName = useCallback((a, b) => {
    const nameA = `${a.firstName || ""} ${a.lastName || ""}`.toLowerCase();
    const nameB = `${b.firstName || ""} ${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 processedData = useMemo(() => {
    let filteredData = showOnlyCheckout
      ? data.filter((item) => item.checkOutTime === null)
      : data;

    // Apply search query filter
    if (searchQuery) {
      const lowerCaseSearchQuery = searchQuery.toLowerCase().trim(); // Trim whitespace

      filteredData = filteredData.filter((att) => {
        // Option 1: Combine firstName, middleName, lastName
        const fullName = [att.firstName, att.middleName, att.lastName]
          .filter(Boolean) // This removes null, undefined, or empty string parts
          .join(" ")
          .toLowerCase();

        // Option 2: Check `employeeName` if it exists and is reliable
        const employeeName = att.employeeName?.toLowerCase() || "";

        // Option 3: Check `employeeId`
        const employeeId = att.employeeId?.toLowerCase() || "";

        // Check if the search query is included in any of the relevant fields
        return (
          fullName.includes(lowerCaseSearchQuery) ||
          employeeName.includes(lowerCaseSearchQuery) ||
          employeeId.includes(lowerCaseSearchQuery)
        );
      });
    }

    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
    return sortedDates.flatMap((date) => groupedByDate[date]);
  }, [data, showOnlyCheckout, searchQuery, isSameDay, isBeforeToday, sortByName]);

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

  // Effect to reset pagination when search query changes
  useEffect(() => {
    resetPage();
  }, [searchQuery, resetPage]); // Add resetPage to dependencies

  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
        );
        dispatch(setAttendanceData(updatedAttendance)); // Update Redux store
      }
    },
    [projectId, dateRange, data, dispatch]
  );

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

  const employeeHandler = useCallback(
    (msg) => {
      const { startDate, endDate } = dateRange;
      dispatch(
        fetchAttendanceData({
          projectId,
          fromDate: startDate,
          toDate: endDate,
        })
      );
    },
    [projectId, dateRange, dispatch]
  );

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

  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: "200px", display: 'flex' }}
      >
        {processedData && processedData.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={attendance.id || 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 && (
            <div
              className="d-flex justify-content-center align-items-center text-muted"
              style={{
                width: "100%",
              }}
            >
              No employee logs.
            </div>
          )
        )}
      </div>
      {!loading && !isRefreshing && processedData.length > 20 && (
        <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;