import React, { useEffect, useState, useMemo, useCallback } from "react";
import moment from "moment";
import Avatar from "../common/Avatar";
import { convertShortTime, formatUTCToLocalTime } from "../../utils/dateUtils";
import RenderAttendanceStatus from "./RenderAttendanceStatus";
import { useSelector, useDispatch } from "react-redux";
import DateRangePicker from "../common/DateRangePicker";
import {
  clearCacheKey,
  getCachedData,
  useSelectedProject,
} from "../../slices/apiDataManager";
import eventBus from "../../services/eventBus";
import AttendanceRepository from "../../repositories/AttendanceRepository";
import { useAttendancesLogs } from "../../hooks/useAttendance";
import { queryClient } from "../../layouts/AuthLayout";
import { ITEMS_PER_PAGE } from "../../utils/constants";
import { useNavigate } from "react-router-dom";
import { SpinnerLoader } from "../common/Loader";

const usePagination = (data, itemsPerPage) => {
  const [currentPage, setCurrentPage] = useState(1);
  // const maxPage = Math.ceil(data.length / itemsPerPage);
  const maxPage = Math.max(1, 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 paginate = useCallback((pageNumber) => {
    // keep page within 1..maxPage
    const p = Math.max(1, Math.min(pageNumber, maxPage));
    setCurrentPage(p);
  }, [maxPage]);
  const resetPage = useCallback(() => setCurrentPage(1), []);

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

const AttendanceLog = ({ handleModalData, searchTerm, organizationId }) => {
  const selectedProject = useSelectedProject();
  const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" });
  const dispatch = useDispatch();
  const [loading, setLoading] = useState(false);
  const [showPending, setShowPending] = useState(false);
  const [isRefreshing, setIsRefreshing] = useState(false);
  const navigate = useNavigate();

  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 + a.lastName).toLowerCase();
    const nameB = (b.firstName + b.lastName).toLowerCase();
    return nameA.localeCompare(nameB);
  };

  const { data = [], isLoading, error, refetch, isFetching } = useAttendancesLogs(
    selectedProject,
    dateRange.startDate,
    dateRange.endDate,
    organizationId
  );

  const processedData = useMemo(() => {
    const filteredData = showPending
      ? 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];

    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;
    }, {});

    const sortedDates = Object.keys(groupedByDate).sort((a, b) => new Date(b) - new Date(a));
    return sortedDates.flatMap((date) => groupedByDate[date]);
  }, [data, showPending]);

  const filteredSearchData = useMemo(() => {
    if (!searchTerm) return processedData;

    const lowercased = searchTerm.toLowerCase();
    return processedData.filter((item) =>
      `${item.firstName} ${item.lastName}`.toLowerCase().includes(lowercased)
    );
  }, [processedData, searchTerm]);

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

  // useEffect(() => {
  //   resetPage();
  // }, [filteredSearchData]);

  useEffect(() => {
    if (currentPage > totalPages) {
      paginate(totalPages || 1);
    }
    // NOTE: do NOT force reset to page 1 here — keep the same page if still valid
  }, [filteredSearchData, totalPages, currentPage, paginate]);

  const handler = useCallback(
    (msg) => {
      const { startDate, endDate } = dateRange;
      const checkIn = msg.response.checkInTime.substring(0, 10);

      if (selectedProject === msg.projectId && startDate <= checkIn && checkIn <= endDate) {
        queryClient.setQueriesData(["attendanceLogs"], (oldData) => {
          if (!oldData) {
            queryClient.invalidateQueries({ queryKey: ["attendanceLogs"] });
            return;
          }
          return oldData.map((record) =>
            record.id === msg.response.id ? { ...record, ...msg.response } : record
          );
        });
      }
    },
    [selectedProject, dateRange]
  );

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

  const employeeHandler = useCallback(
    (msg) => {
      const { startDate, endDate } = dateRange;
      if (data.some((item) => item.employeeId == msg.employeeId)) {
        refetch();
      }
    },
    [data, refetch]
  );

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



  return (
    <>
      <div
        className="dataTables_length text-start py-2 d-flex flex-wrap justify-content-between align-items-center"
        id="DataTables_Table_0_length"
      >
        {/* Left Side - Date Picker */}
        <div className="d-flex align-items-center">
          <DateRangePicker
            onRangeChange={setDateRange}
            defaultStartDate={yesterday}
          />
        </div>

        {/* Right Side - Pending Attendance Switch */}
        <div className="form-check form-switch d-flex align-items-center mb-2">
          <input
            type="checkbox"
            className="form-check-input"
            role="switch"
            id="inactiveEmployeesCheckbox"
            disabled={isFetching}
            checked={showPending}
            onChange={(e) => setShowPending(e.target.checked)}
          />
          <label
            className="form-check-label ms-2"
            htmlFor="inactiveEmployeesCheckbox"
          >
            Pending Attendance
          </label>
        </div>
      </div>


      <div
        className="table-responsive modal-min-h text-nowrap"
        style={{ minHeight: "200px" }}
      >
        {isLoading ? (
          <div
            className="d-flex justify-content-center align-items-center"
            style={{ minHeight: "50vh" }}
          >
            <SpinnerLoader />
          </div>
        ) : filteredSearchData?.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>Organization</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>
              {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={8} className="text-start">
                        <strong className="d-inline-block my-1 ms-2">
                          {formatUTCToLocalTime(currentDate)}
                        </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
                            onClick={() =>
                              navigate(`/employee/${attendance.employeeId}?for=attendance`)
                            }
                            className="text-heading text-truncate cursor-pointer"
                          >
                            <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>{attendance.organizationName || "--"}</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>
        ) : (
          <div className="my-12">
            <span className="text-secondary">
              No attendance record found in selected date range.
            </span>
          </div>
        )}
      </div>
      {paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && (
        <div
          className="d-flex justify-content-center align-items-center text-secondary"
          style={{ height: "200px" }}
        >
          No Record Available !
        </div>
      )}
      {filteredSearchData.length > ITEMS_PER_PAGE && (
        <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;
