// Employees.jsx
import React, { useState, useEffect, useMemo, useRef } from "react";
import Swal from "sweetalert2";
import { confirmHoldToDelete } from "../../components/utils/confirmHoldToDelete";
import ModernButton from "../ui/ModernButton";
import EmployeeModal from "./EmployeeModal";
import EmployeeAssignmentModal from "./EmployeeAssignmentModal";
import AssignScheduleModal from "../schedule-manager/schedule-manager-components/AssignScheduleModal";
import { useLocation } from "react-router-dom";
import "../../../Styles/components/employee/employeejsx.css";
import BASE_URL from "@backend/server/config";
import Breadcrumbs from "../breadcrumbs/Breadcrumbs";
import BulkEmployeeActionsModal from "./BulkEmployeeActionsModal";
import EmployeeListView from "./employeeTableMode/employeeListView";
import EmployeeGridView from "./employeeTableMode/employeeGridView";
import { useSession } from "../../context/SessionContext";
import { secureGetItem } from "../utils/secureStorage";
import usePermissions from "../../users/hooks/usePermissions";
import { Tooltip } from "@mui/material";
import Tabs from "../breadcrumbs/Tabs";
import {
  Printer,
  Trash2,
  Search,
  Plus,
  AlignJustify,
  Grid3x3,
  UserRoundX,
  Users,
  Briefcase,
  Building2,
  Settings,
  ChevronLeft,
  ChevronRight,
  Fingerprint,
} from "lucide-react";
import { useNavigate } from "react-router-dom";

function Employees() {
  const { state } = useLocation();
  const { user } = useSession();
  const { permissions, loading: permLoading } = usePermissions(user?.username);
  const [customId, setCustomId] = useState("");

  const [statusFilter, setStatusFilter] = useState("active");
  const [typeFilter, setTypeFilter] = useState("all");
  const [branchFilter, setBranchFilter] = useState("all");
  const [departmentFilter, setDepartmentFilter] = useState("all");
  const [positionFilter, setPositionFilter] = useState("all");

  const navigate = useNavigate();

  const [employees, setEmployees] = useState([]);
  const [isInitialLoading, setIsInitialLoading] = useState(true);
  const [isListRefreshing, setIsListRefreshing] = useState(false);
  const [isSavingEmployee, setIsSavingEmployee] = useState(false);
  const [isLoadingLookups, setIsLoadingLookups] = useState(false);
  const [error, setError] = useState("");
  const [refreshNotice, setRefreshNotice] = useState("");
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [editingEmployee, setEditingEmployee] = useState(null);
  const [selectedEmployees, setSelectedEmployees] = useState([]);
  const [searchInput, setSearchInput] = useState("");
  const [searchQuery, setSearchQuery] = useState("");
  const [activeView, setActiveView] = useState("list");
  const [isBulkModalOpen, setIsBulkModalOpen] = useState(false);
  const [bulkApplying, setBulkApplying] = useState(false);
  const [assignmentOptions, setAssignmentOptions] = useState({
    brands: [],
    branches: [],
  });
  const [assignmentModalEmployee, setAssignmentModalEmployee] = useState(null);
  const [isAssignmentModalOpen, setIsAssignmentModalOpen] = useState(false);

  const [mobileFiltersOpen, setMobileFiltersOpen] = useState(false);
  const [mobileActionsOpen, setMobileActionsOpen] = useState(false);

  const [isAssignModalOpen, setIsAssignModalOpen] = useState(false);
  const [assignPreselectedEmployees, setAssignPreselectedEmployees] = useState(
    [],
  );
  const [gridCurrentPage, setGridCurrentPage] = useState(1);
  const [workTimes, setWorkTimes] = useState([]);

  const tabs = useMemo(
    () => [
      {
        key: "employees",
        label: "Employee List",
        sublabel: "View & Manage Employees",
        icon: Users,
        onClick: () => navigate("/employees"),
      },
      {
        key: "departments",
        label: "Departments",
        sublabel: "Manage Employee Departments",
        icon: Briefcase,
        onClick: () => navigate("/department"),
      },
      {
        key: "branches",
        label: "Branch",
        sublabel: "Manage Branches",
        icon: Building2,
        onClick: () => navigate("/branches"),
      },
      {
        key: "biometrics",
        label: "Biometrics",
        sublabel: "Manage Biometrics",
        icon: Fingerprint,
        onClick: () => navigate("/UsersBiometrics"),
      },
    ],
    [navigate],
  );

  const [assignModalKey, setAssignModalKey] = useState(0);
  const latestEmployeesRequestRef = useRef(0);

  const normalizedRole = String(user?.role || "")
    .toUpperCase()
    .replace(/_/g, " ");
  const canManageAssignments = ["ADMIN", "SUPER ADMIN"].includes(
    normalizedRole,
  );

  const cleanupBlockingOverlays = () => {
    if (typeof document === "undefined") return;

    try {
      document.body.classList.remove("swal2-shown", "swal2-height-auto");
      document.body.style.removeProperty("overflow");
      document.body.style.removeProperty("padding-right");
      document.body.style.removeProperty("pointer-events");

      document.documentElement.style.removeProperty("overflow");
      document.documentElement.style.removeProperty("padding-right");

      document.querySelectorAll(".swal2-container").forEach((el) => {
        const popup = el.querySelector(".swal2-popup");
        const backdropActive = el.classList.contains("swal2-backdrop-show");
        const toastActive = el.classList.contains("swal2-toast-shown");

        if (!popup && !backdropActive && !toastActive) {
          el.remove();
        }
      });

      if (!isAssignModalOpen) {
        document.querySelectorAll(".MuiModal-root").forEach((el) => {
          const hidden =
            el.classList.contains("MuiModal-hidden") ||
            el.getAttribute("aria-hidden") === "true";

          if (hidden) {
            el.style.pointerEvents = "none";
            const backdrop = el.querySelector(".MuiBackdrop-root");
            if (backdrop) backdrop.style.pointerEvents = "none";
          }
        });

        document.querySelectorAll(".MuiBackdrop-root").forEach((el) => {
          const style = window.getComputedStyle(el);
          const hidden =
            style.visibility === "hidden" || Number(style.opacity || "1") === 0;

          if (hidden) {
            el.style.pointerEvents = "none";
          }
        });
      }
    } catch (err) {
      console.warn("Overlay cleanup failed:", err);
    }
  };

  const breadcrumbItems = [
    !permLoading &&
    permissions?.employee_list && {
      key: "dashboard",
      label: "Employee Lists",
      path: "/employees",
    },
    !permLoading &&
    permissions?.department && {
      key: "employees",
      label: "Departments",
      path: "/department",
    },
    !permLoading &&
    permissions?.branches && {
      key: "branches",
      label: "Branches",
      path: "/branches",
    },
    !permLoading &&
    permissions?.user_biometrics && {
      key: "biometrics",
      label: "Biometrics",
      path: "/UsersBiometrics",
    },
  ].filter(Boolean);

  const fetchEmployees = async ({
    background = false,
    failureNotice = "",
  } = {}) => {
    const requestId = latestEmployeesRequestRef.current + 1;
    latestEmployeesRequestRef.current = requestId;
    const showAsBackgroundRefresh = background || employees.length > 0;

    if (showAsBackgroundRefresh) {
      setIsListRefreshing(true);
    } else {
      setIsInitialLoading(true);
    }

    setError("");
    if (!failureNotice) setRefreshNotice("");

    try {
      const response = await fetch(`${BASE_URL}/api/employeesSide/employees`);
      if (!response.ok) {
        throw new Error(`Employee list request failed (${response.status})`);
      }

      const data = await response.json();

      if (requestId !== latestEmployeesRequestRef.current) return;

      if (data.message) {
        console.warn("employees.php message:", data.message);
        setEmployees([]);
      } else {
        setEmployees(Array.isArray(data) ? data : []);
      }
      setRefreshNotice("");
    } catch (error) {
      if (requestId !== latestEmployeesRequestRef.current) return;

      console.error("Error fetching employee data:", error);
      if (showAsBackgroundRefresh) {
        setRefreshNotice(
          failureNotice ||
            "List refresh failed. Your last successful changes remain visible.",
        );
      } else {
        setError("Error fetching employees. Check console.");
        setEmployees([]);
      }
    } finally {
      if (requestId === latestEmployeesRequestRef.current) {
        if (showAsBackgroundRefresh) {
          setIsListRefreshing(false);
        } else {
          setIsInitialLoading(false);
        }
      }
    }
  };

  const fetchAssignmentOptions = async () => {
    try {
      const response = await fetch(
        `${BASE_URL}/api/employee_assignment/read_assignment_options`,
      );
      const data = await response.json();
      const source = data?.data || data || {};

      setAssignmentOptions({
        brands: Array.isArray(source.brands) ? source.brands : [],
        branches: Array.isArray(source.branches) ? source.branches : [],
      });
    } catch (error) {
      console.error("Error fetching assignment options:", error);
      setAssignmentOptions({ brands: [], branches: [] });
    }
  };

  const fetchWorkTimes = async () => {
    try {
      const res = await fetch(`${BASE_URL}/api/work_time/read_work_time`);
      const data = await res.json();
      setWorkTimes(Array.isArray(data) ? data : []);
    } catch (err) {
      console.warn("Failed to fetch workTimes:", err);
      setWorkTimes([]);
    }
  };

  const fetchLookupData = async () => {
    setIsLoadingLookups(true);
    try {
      await Promise.all([fetchWorkTimes(), fetchAssignmentOptions()]);
    } finally {
      setIsLoadingLookups(false);
    }
  };

  useEffect(() => {
    let isMounted = true;
    const init = async () => {
      fetchEmployees();
      fetchLookupData();
    };
    if (isMounted) init();
    return () => {
      isMounted = false;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    const timeoutId = window.setTimeout(() => {
      setSearchQuery(searchInput);
    }, 200);

    return () => window.clearTimeout(timeoutId);
  }, [searchInput]);

  useEffect(() => {
    setGridCurrentPage(1);
  }, [
    searchQuery,
    statusFilter,
    typeFilter,
    branchFilter,
    departmentFilter,
    positionFilter,
  ]);

  useEffect(() => {
    if (
      isModalOpen ||
      isAssignModalOpen ||
      isBulkModalOpen ||
      isAssignmentModalOpen
    )
      return;

    if (typeof window === "undefined") return;

    const rafId = window.requestAnimationFrame(() => {
      cleanupBlockingOverlays();
    });
    const timeoutId = window.setTimeout(() => {
      cleanupBlockingOverlays();
    }, 250);

    return () => {
      window.cancelAnimationFrame(rafId);
      window.clearTimeout(timeoutId);
    };
  }, [isModalOpen, isAssignModalOpen, isBulkModalOpen, isAssignmentModalOpen]);

  const handleListView = () => {
    setActiveView("list");
  };

  const handleGridView = () => {
    setActiveView("grid");
  };

  const patchSavedEmployee = (savedEmployee, responseData = {}) => {
    const oldEmployeeId = String(
      savedEmployee.old_employee_id || savedEmployee.employee_id || "",
    );
    const nextEmployeeId = String(
      responseData.employee_id || savedEmployee.employee_id || oldEmployeeId,
    );

    if (!oldEmployeeId) return;

    const assignment = responseData.assignment || {};
    const patch = {
      ...savedEmployee,
      ...assignment,
      employee_id: nextEmployeeId,
    };

    delete patch.old_employee_id;
    delete patch.current_user;
    delete patch.password;

    if (patch.brand_id) {
      const brand = assignmentOptions.brands.find(
        (item) => String(item.brand_id) === String(patch.brand_id),
      );
      if (brand?.brand_name) patch.brand_name = brand.brand_name;
    }

    if (Object.prototype.hasOwnProperty.call(patch, "branch_id")) {
      const branch = assignmentOptions.branches.find(
        (item) => String(item.branch_id) === String(patch.branch_id),
      );
      patch.branch_name =
        assignment.branch_name ??
        branch?.branch_name ??
        branch?.name ??
        patch.branch_name ??
        null;
    }

    setEmployees((previous) =>
      previous.map((employee) =>
        String(employee.employee_id) === oldEmployeeId
          ? { ...employee, ...patch }
          : employee,
      ),
    );

    setEditingEmployee((previous) =>
      previous && String(previous.employee_id) === oldEmployeeId
        ? { ...previous, ...patch }
        : previous,
    );
  };

  const handleAddOrUpdateEmployee = async (newEmployee, mode = "add") => {
    const url =
      mode === "update"
        ? `${BASE_URL}/api/employeesSide/update_employee`
        : `${BASE_URL}/api/employeesSide/add_employee`;
    const method = mode === "update" ? "PUT" : "POST";

    const currentUser = secureGetItem("user", {}, window.localStorage) || {};

    const payload = {
      ...newEmployee,
      current_user: {
        full_name: currentUser?.full_name || currentUser?.username || "Unknown",
        role: currentUser?.role || "GUEST",
      },
    };

    try {
      setIsSavingEmployee(true);
      setRefreshNotice("");

      const response = await fetch(url, {
        method,
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });

      const text = await response.text();
      let data;

      try {
        data = JSON.parse(text);
      } catch {
        console.error("Server returned non-JSON:", text);
        return {
          status: "error",
          message: "Unexpected server response. Check console.",
        };
      }


      if (data.status === "success" || data.success) {
        if (mode === "update") {
          patchSavedEmployee(newEmployee, data);
          fetchEmployees({
            background: true,
            failureNotice:
              "Saved, but list refresh failed. Please reload if needed.",
          });
        } else {
          await fetchEmployees();
        }

        return {
          ...data,
          status: "success",
          employee_id: data.employee_id || newEmployee.employee_id,
          email: data.email || newEmployee.email,
          password: data.password || data.generated_password || null,
        };
      }

      return {
        ...data,
        status: "error",
        message: data.message || "Failed to save employee.",
      };
    } catch (error) {
      console.error("Error saving employee:", error);
      return {
        status: "error",
        message: error.message || "Network error",
      };
    } finally {
      setIsSavingEmployee(false);
    }
  };

  const handleEditEmployee = (employee) => {
    setEditingEmployee(employee);
    setIsModalOpen(true);
  };

  const handleOpenAssignmentModal = (employee) => {
    if (!canManageAssignments) return;
    setAssignmentModalEmployee(employee);
    setIsAssignmentModalOpen(true);
  };

  const handleAssignmentSaved = async () => {
    await fetchEmployees();
  };

  const handleDeleteEmployee = async (employee_id) => {
    const result = await confirmHoldToDelete({
      title: "Are you sure?",
      text: "This action cannot be undone!",
    });

    if (!result.isConfirmed) return;

    try {
      const currentUser = secureGetItem("user", {}, window.localStorage) || {};
      const response = await fetch(
        `${BASE_URL}/api/employeesSide/delete_employee?id=${employee_id}&full_name=${encodeURIComponent(currentUser.full_name || "")}&role=${encodeURIComponent(currentUser.role || "")}`,
        {
          method: "DELETE",
          headers: { "Content-Type": "application/json" },
        },
      );

      const data = await response.json();
      if (data.success || data.status === "success") {
        setEmployees((prev) =>
          prev.filter((emp) => emp.employee_id !== employee_id),
        );
        Swal.fire({
          icon: "success",
          title: "Deleted",
          text: data.message || "Employee deleted",
        });
      } else {
        Swal.fire({
          icon: "error",
          title: "Error",
          text: data.message || "Failed to delete",
        });
      }
    } catch (error) {
      console.error("Error deleting employee:", error);
      Swal.fire({
        icon: "error",
        title: "Error",
        text: "Something went wrong. See console.",
      });
    }
  };

  const handleToggleStatus = async (employee) => {
    const newStatus = employee.status === "active" ? "inactive" : "active";
    try {
      const response = await fetch(
        `${BASE_URL}/api/employeesSide/update_employee_status`,
        {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            employee_id: employee.employee_id,
            status: newStatus,
          }),
        },
      );
      const data = await response.json();
      if (data.success || data.status === "success") {
        setEmployees((prev) =>
          prev.map((emp) =>
            emp.employee_id === employee.employee_id
              ? { ...emp, status: newStatus }
              : emp,
          ),
        );
        Swal.fire("Updated!", `Employee marked as ${newStatus}`, "success");
      } else {
        Swal.fire("Error!", data.message || "Status update failed.", "error");
      }
    } catch (error) {
      console.error("Error updating status:", error);
      Swal.fire("Error!", "Something went wrong.", "error");
    }
  };

  const handleDeleteSelectedEmployees = async () => {
    if (selectedEmployees.length === 0) {
      Swal.fire("Info", "No employees selected.", "info");
      return;
    }

    const confirmed = await confirmHoldToDelete({
      title: `Delete ${selectedEmployees.length} employees?`,
      text: "This action cannot be undone.",
    });
    if (!confirmed.isConfirmed) return;

    try {
      const response = await fetch(
        `${BASE_URL}/api/employeesSide/delete_multiple`,
        {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ employee_ids: selectedEmployees }),
        },
      );
      const data = await response.json();
      if (data.success) {
        setEmployees((prev) =>
          prev.filter((emp) => !selectedEmployees.includes(emp.employee_id)),
        );
        setSelectedEmployees([]);
        Swal.fire("Deleted", "Selected employees deleted.", "success");
      } else {
        Swal.fire(
          "Error",
          data.message || "Failed to delete employees.",
          "error",
        );
      }
    } catch (error) {
      console.error("Error deleting employees:", error);
      Swal.fire("Error", "Error deleting employees. See console.", "error");
    }
  };

  const handleOpenBulkSettings = () => {
    if (selectedEmployees.length === 0) {
      Swal.fire("Info", "Select employees first.", "info");
      return;
    }

    setIsBulkModalOpen(true);
  };

  const handleBulkUpdateEmployees = async (updates) => {
    if (selectedEmployees.length === 0) {
      Swal.fire("Info", "Select employees first.", "info");
      return;
    }

    const payload = {
      employee_ids: selectedEmployees,
      ...updates,
    };

    const currentUser = secureGetItem("user", {}, window.localStorage) || {};
    payload.current_user = {
      full_name: currentUser?.full_name || currentUser?.username || "Unknown",
      role: currentUser?.role || "GUEST",
    };

    setBulkApplying(true);
    try {
      const response = await fetch(
        `${BASE_URL}/api/employeesSide/bulk_update_employees`,
        {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(payload),
        },
      );

      const text = await response.text();
      let data;
      try {
        data = JSON.parse(text);
      } catch {
        console.error("Bulk update returned non-JSON:", text);
        Swal.fire(
          "Error",
          "Unexpected server response. Check console.",
          "error",
        );
        return;
      }

      if (data.success || data.status === "success") {
        await fetchEmployees();
        setSelectedEmployees([]);
        setIsBulkModalOpen(false);
        Swal.fire(
          "Updated",
          data.message || "Selected employees were updated.",
          "success",
        );
      } else {
        Swal.fire("Error", data.message || "Bulk update failed.", "error");
      }
    } catch (error) {
      console.error("Error bulk updating employees:", error);
      Swal.fire("Error", "Something went wrong. See console.", "error");
    } finally {
      setBulkApplying(false);
    }
  };

  const handleSelectAll = (event, visibleEmployees = employees) => {
    const visibleIds = visibleEmployees.map((emp) => emp.employee_id);
    if (event.target.checked) {
      setSelectedEmployees((prev) =>
        Array.from(new Set([...prev, ...visibleIds])),
      );
    } else {
      setSelectedEmployees((prev) =>
        prev.filter((id) => !visibleIds.includes(id)),
      );
    }
  };

  const handleSelectEmployee = (employeeId) => {
    setSelectedEmployees((prev) =>
      prev.includes(employeeId)
        ? prev.filter((id) => id !== employeeId)
        : [...prev, employeeId],
    );
  };

  const normalize = (v) =>
    v === undefined || v === null || v === "" ? "Not assigned" : String(v);

  const branchDisplayName = (employee) => {
    if (employee?.assignment_status === "invalid_no_brand") {
      return "Invalid: No Brand";
    }

    return employee?.branch_name ? employee.branch_name : "Unassigned Branch";
  };

  const matchesBaseFilters = (
    emp,
    {
      ignoreBranch = false,
      ignoreDept = false,
      ignorePos = false,
      ignoreType = false,
      ignoreStatus = false,
    } = {},
  ) => {
    const fullName = [emp.first_name, emp.middle_name, emp.last_name]
      .filter(Boolean)
      .join(" ")
      .toLowerCase();
    
    const safeQuery = searchQuery.replace(/\s+/g, " ").toLowerCase().trim();
    const queryWords = safeQuery ? safeQuery.split(" ") : [];
    
    const haystack = [
      fullName,
      emp.employee_id,
      emp.person_id,
      emp.biometrics_id
    ]
      .filter(Boolean)
      .join(" ")
      .toLowerCase()
      .replace(/\s+/g, " ");

    const matchesSearch = queryWords.length === 0 || queryWords.every(word => haystack.includes(word));
    const matchesStatus = ignoreStatus
      ? true
      : statusFilter === "all" || emp.status === statusFilter;
    const matchesType = ignoreType
      ? true
      : typeFilter === "all" || (emp.employee_type || "Unknown") === typeFilter;

    const empBranch = branchDisplayName(emp);
    const empDept = normalize(emp.department_name);
    const empPos = normalize(emp.position_name);

    const matchesBranch = ignoreBranch
      ? true
      : branchFilter === "all" || empBranch === branchFilter;
    const matchesDept = ignoreDept
      ? true
      : departmentFilter === "all" || empDept === departmentFilter;
    const matchesPos = ignorePos
      ? true
      : positionFilter === "all" || empPos === positionFilter;

    return (
      matchesSearch &&
      matchesStatus &&
      matchesType &&
      matchesBranch &&
      matchesDept &&
      matchesPos
    );
  };

  const branchesWithCount = useMemo(() => {
    const map = new Map();
    assignmentOptions.branches.forEach((branch) => {
      const name = branch.branch_name || branch.name;
      if (name && !map.has(name)) map.set(name, 0);
    });
    employees.forEach((emp) => {
      const b = branchDisplayName(emp);
      const baseMatch = matchesBaseFilters(emp, {
        ignoreBranch: true,
        ignoreDept: true,
        ignorePos: true,
      });
      if (!map.has(b)) map.set(b, 0);
      if (baseMatch) map.set(b, map.get(b) + 1);
    });
    return Array.from(map.entries())
      .map(([name, count]) => ({ name, count }))
      .sort((a, b) => a.name.localeCompare(b.name));
  }, [
    employees,
    assignmentOptions.branches,
    searchQuery,
    statusFilter,
    typeFilter,
    branchFilter,
    departmentFilter,
    positionFilter,
  ]);

  const departmentsWithCount = useMemo(() => {
    const map = new Map();
    employees.forEach((emp) => {
      const b = branchDisplayName(emp);
      const d = normalize(emp.department_name);
      const baseMatch = matchesBaseFilters(emp, {
        ignoreBranch: false,
        ignoreDept: true,
        ignorePos: true,
      });
      if ((branchFilter === "all" || b === branchFilter) && baseMatch) {
        if (!map.has(d)) map.set(d, 0);
        map.set(d, map.get(d) + 1);
      }
    });
    return Array.from(map.entries())
      .map(([name, count]) => ({ name, count }))
      .sort((a, b) => a.name.localeCompare(b.name));
  }, [
    employees,
    branchFilter,
    searchQuery,
    statusFilter,
    typeFilter,
    departmentFilter,
    positionFilter,
  ]);

  const positionsWithCount = useMemo(() => {
    const map = new Map();
    employees.forEach((emp) => {
      const b = branchDisplayName(emp);
      const d = normalize(emp.department_name);
      const p = normalize(emp.position_name);
      const baseMatch = matchesBaseFilters(emp, {
        ignoreBranch: false,
        ignoreDept: false,
        ignorePos: true,
      });
      if (
        (branchFilter === "all" || b === branchFilter) &&
        (departmentFilter === "all" || d === departmentFilter) &&
        baseMatch
      ) {
        if (!map.has(p)) map.set(p, 0);
        map.set(p, map.get(p) + 1);
      }
    });
    return Array.from(map.entries())
      .map(([name, count]) => ({ name, count }))
      .sort((a, b) => a.name.localeCompare(b.name));
  }, [
    employees,
    branchFilter,
    departmentFilter,
    searchQuery,
    statusFilter,
    typeFilter,
    positionFilter,
  ]);

  const typesWithCount = useMemo(() => {
    const map = new Map();
    employees.forEach((emp) => {
      const b = branchDisplayName(emp);
      const d = normalize(emp.department_name);
      const p = normalize(emp.position_name);
      const t = emp.employee_type || "Unknown";
      const baseMatch = matchesBaseFilters(emp, {
        ignoreType: true,
        ignoreBranch: false,
        ignoreDept: false,
        ignorePos: false,
        ignoreStatus: false,
      });
      if (
        (branchFilter === "all" || b === branchFilter) &&
        (departmentFilter === "all" || d === departmentFilter) &&
        (positionFilter === "all" || p === positionFilter) &&
        baseMatch
      ) {
        if (!map.has(t)) map.set(t, 0);
        map.set(t, map.get(t) + 1);
      }
    });
    return Array.from(map.entries())
      .map(([name, count]) => ({ name, count }))
      .sort((a, b) => a.name.localeCompare(b.name));
  }, [
    employees,
    branchFilter,
    departmentFilter,
    positionFilter,
    searchQuery,
    statusFilter,
    typeFilter,
  ]);

  const statusWithCount = useMemo(() => {
    const map = { active: 0, inactive: 0 };
    employees.forEach((emp) => {
      const b = branchDisplayName(emp);
      const d = normalize(emp.department_name);
      const p = normalize(emp.position_name);
      const baseMatch = matchesBaseFilters(emp, {
        ignoreStatus: true,
        ignoreBranch: false,
        ignoreDept: false,
        ignorePos: false,
        ignoreType: false,
      });
      if (
        (branchFilter === "all" || b === branchFilter) &&
        (departmentFilter === "all" || d === departmentFilter) &&
        (positionFilter === "all" || p === positionFilter) &&
        baseMatch
      ) {
        const s = emp.status === "active" ? "active" : "inactive";
        map[s] = (map[s] || 0) + 1;
      }
    });
    return map;
  }, [
    employees,
    branchFilter,
    departmentFilter,
    positionFilter,
    searchQuery,
    typeFilter,
    statusFilter,
  ]);

  const filteredEmployees = employees
    .filter((employee) => {
      const safeQuery = searchQuery.replace(/\s+/g, " ").toLowerCase().trim();
      const queryWords = safeQuery ? safeQuery.split(" ") : [];

      const fullName = [employee.first_name, employee.middle_name, employee.last_name]
        .filter(Boolean)
        .join(" ")
        .toLowerCase();

      const haystack = [
        fullName,
        employee.employee_id,
        employee.person_id,
        employee.biometrics_id
      ]
        .filter(Boolean)
        .join(" ")
        .toLowerCase()
        .replace(/\s+/g, " ");

      const matchesSearch = queryWords.length === 0 || queryWords.every(word => haystack.includes(word));
      const matchesStatus =
        statusFilter === "all" || employee.status === statusFilter;
      const matchesType =
        typeFilter === "all" || employee.employee_type === typeFilter;

      const empBranch = branchDisplayName(employee);
      const empDept = normalize(employee.department_name);
      const empPos = normalize(employee.position_name);

      const matchesBranch =
        branchFilter === "all" || empBranch === branchFilter;
      const matchesDept =
        departmentFilter === "all" || empDept === departmentFilter;
      const matchesPos = positionFilter === "all" || empPos === positionFilter;

      return (
        matchesSearch &&
        matchesStatus &&
        matchesType &&
        matchesBranch &&
        matchesDept &&
        matchesPos
      );
    })
    .sort((a, b) => {
      if (a.status === "active" && b.status !== "active") return -1;
      if (a.status !== "active" && b.status === "active") return 1;
      return 0;
    });

  const gridItemsPerPage = 18;
  const gridTotalPages = Math.ceil(filteredEmployees.length / gridItemsPerPage);
  const paginatedGridEmployees =
    activeView === "grid"
      ? filteredEmployees.slice(
        (gridCurrentPage - 1) * gridItemsPerPage,
        gridCurrentPage * gridItemsPerPage,
      )
      : filteredEmployees;

  const gridPageNumbers = useMemo(() => {
    const pages = [];
    for (let i = 1; i <= gridTotalPages; i++) {
      if (
        i === 1 ||
        i === gridTotalPages ||
        Math.abs(i - gridCurrentPage) <= 1
      ) {
        pages.push(i);
      } else if (pages[pages.length - 1] !== "...") {
        pages.push("...");
      }
    }
    return pages;
  }, [gridTotalPages, gridCurrentPage]);

  const handlePrintSelected = () => {
    const selectedData = employees.filter((emp) =>
      selectedEmployees.includes(emp.employee_id),
    );
    const printWindow = window.open("", "_blank", "width=1000,height=800");
    const tableHtml = `
      <!DOCTYPE html>
      <html>
        <head>
          <title>Employee Directory</title>
          <style>
            @page {
              size: landscape;
              margin: 15mm;
            }
            body {
              font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
              color: #334155;
              background-color: #ffffff;
              margin: 0;
              padding: 0;
              padding: 20px;
              -webkit-print-color-adjust: exact;
              print-color-adjust: exact;
            }
            .header {
              display: flex;
              justify-content: space-between;
              align-items: flex-end;
              border-bottom: 2px solid #e2e8f0;
              padding-bottom: 12px;
              margin-bottom: 24px;
            }
            .header h1 {
              margin: 0;
              color: #0f172a;
              font-size: 24px;
              font-weight: 700;
              letter-spacing: -0.025em;
            }
            .header p {
              margin: 4px 0 0 0;
              color: #64748b;
              font-size: 12px;
            }
            .header-meta {
              text-align: right;
              font-size: 11px;
              color: #94a3b8;
              line-height: 1.5;
            }
            table {
              width: 100%;
              border-collapse: collapse;
              font-size: 11px;
            }
            th {
              background-color: #f8fafc;
              color: #475569;
              font-weight: 600;
              text-transform: uppercase;
              letter-spacing: 0.05em;
              padding: 10px 12px;
              text-align: left;
              border-bottom: 1px solid #cbd5e1;
            }
            td {
              padding: 12px;
              border-bottom: 1px solid #f1f5f9;
              color: #334155;
            }
            tbody tr:nth-child(even) {
              background-color: #f8fafc;
            }
            .footer {
              margin-top: 32px;
              text-align: center;
              font-size: 10px;
              color: #94a3b8;
              border-top: 1px solid #e2e8f0;
              padding-top: 12px;
            }
            .emp-name {
              font-weight: 600;
              color: #0f172a;
            }
            .emp-id {
              font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
              color: #64748b;
              font-size: 10px;
            }
          </style>
        </head>
        <body>
          <div class="header">
            <div>
              <h1>Employee Directory</h1>
              <p>Selected Personnel Records</p>
            </div>
            <div class="header-meta">
              Generated on: ${new Date().toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric", hour: "2-digit", minute: "2-digit" })}<br/>
              Total Records: ${selectedData.length}
            </div>
          </div>
          <table>
            <thead>
              <tr>
                <th width="8%">ID</th>
                <th width="18%">Name</th>
                <th width="14%">Branch</th>
                <th width="13%">Department</th>
                <th width="14%">Position</th>
                <th width="14%">Email</th>
                <th width="10%">Contact</th>
                <th width="9%">Date of Birth</th>
              </tr>
            </thead>
            <tbody>
              ${selectedData
        .map(
          (emp) => `
                <tr>
                  <td class="emp-id">${emp.employee_id}</td>
                  <td>
                    <div class="emp-name">${emp.last_name}, ${emp.first_name} ${emp.middle_name ? emp.middle_name.charAt(0) + "." : ""}</div>
                  </td>
                  <td>${branchDisplayName(emp)}</td>
                  <td>${emp.department_name || "—"}</td>
                  <td>${emp.position_name || "—"}</td>
                  <td>${emp.email || "—"}</td>
                  <td>${emp.contact_number || "—"}</td>
                  <td>${emp.date_of_birth ? new Date(emp.date_of_birth).toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric" }) : "—"}</td>
                </tr>`,
        )
        .join("")}
            </tbody>
          </table>
          <div class="footer">
            Solidmark Employee Management System &copy; ${new Date().getFullYear()}
          </div>
        </body>
      </html>
    `;
    printWindow.document.write(tableHtml);
    printWindow.document.close();
    printWindow.focus();

    // Timeout ensures web fonts & styles have time to apply before the print dialog freezes the page rendering
    setTimeout(() => {
      printWindow.print();
    }, 250);
  };

  const handleOpenAssign = (employeeIds = []) => {
    setAssignPreselectedEmployees(employeeIds);
    setAssignModalKey(Date.now());
    setIsAssignModalOpen(true);
  };

  const createSchedule = async (payload) => {
    try {
      const r = await fetch(`${BASE_URL}/api/schedule-manager/create-sm`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });
      return await r.json();
    } catch (err) {
      console.error("createSchedule error:", err);
      return { success: false, message: "Network error" };
    }
  };

  const updateSchedule = async (payload) => {
    try {
      const r = await fetch(`${BASE_URL}/api/schedule-manager/update-mp`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });
      return await r.json();
    } catch (err) {
      console.error("updateSchedule error:", err);
      return { success: false, message: "Network error" };
    }
  };

  const deleteSchedule = async (schedule_id) => {
    try {
      const r = await fetch(
        `${BASE_URL}/api/schedule-manager/delete-mp`,
        {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ schedule_id })
        },
      );
      return await r.json();
    } catch (err) {
      console.error("deleteSchedule error:", err);
      return { success: false, message: "Network error" };
    }
  };

  const fetchSchedules = async () => {
    try {
      const r = await fetch(`${BASE_URL}/api/schedule-manager/read-mp`);
      return await r.json();
    } catch (err) {
      console.warn("fetchSchedules error:", err);
      return [];
    }
  };

  const onBranchChange = (val) => {
    setBranchFilter(val);
    setDepartmentFilter("all");
    setPositionFilter("all");
  };

  const onDepartmentChange = (val) => {
    setDepartmentFilter(val);
    setPositionFilter("all");
  };

  const onPositionChange = (val) => {
    setPositionFilter(val);
  };

  const clearAllFilters = () => {
    setBranchFilter("all");
    setDepartmentFilter("all");
    setPositionFilter("all");
    setTypeFilter("all");
    setStatusFilter("active");
  };

  return (
    <div className="container flex w-full gap-y-4">
      <div className="sticky flex flex-col w-full pb-3 pl-5 border-b-2 gap-y-2 Glc-dashboard-bg-header">
        <span className="text-2xl font-semibold">Employee List</span>
        <div className="hidden sm:block">
          <Breadcrumbs items={breadcrumbItems} />
        </div>
      </div>

      <div className="w-full">
        <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
          <div className="relative flex-1">
            <input
              type="text"
              placeholder="Search employees, ID, or attendance..."
              className="w-full h-10 pl-10 pr-3 text-sm border border-gray-200 rounded-lg outline-none bg-gray-50 focus:ring-2 focus:ring-blue-300"
              value={searchInput}
              onChange={(e) => setSearchInput(e.target.value)}
              aria-label="Search employees"
            />
            <div className="absolute text-gray-500 -translate-y-1/2 left-3 top-1/2">
              <Search size={18} />
            </div>
          </div>

          <div className="flex items-center gap-3 mt-2 sm:mt-0">
            <div className="hidden sm:flex sm:items-center sm:gap-3">
              <select
                value={statusFilter}
                onChange={(e) => setStatusFilter(e.target.value)}
                className="px-3 py-2 text-sm bg-white border border-gray-300 rounded-lg"
              >
                <option value="all">
                  All Status (
                  {(statusWithCount.active || 0) +
                    (statusWithCount.inactive || 0)}
                  )
                </option>
                <option value="active">
                  Active ({statusWithCount.active || 0})
                </option>
                <option value="inactive">
                  Inactive ({statusWithCount.inactive || 0})
                </option>
              </select>

              <select
                value={typeFilter}
                onChange={(e) => setTypeFilter(e.target.value)}
                className="px-3 py-2 text-sm bg-white border border-gray-300 rounded-lg"
              >
                <option value="all">
                  All Types ({typesWithCount.reduce((s, t) => s + t.count, 0)})
                </option>
                {typesWithCount.map((t) => (
                  <option key={t.name} value={t.name}>
                    {t.name} ({t.count})
                  </option>
                ))}
              </select>

              <div className="flex items-center gap-2">
                <select
                  value={branchFilter}
                  onChange={(e) => onBranchChange(e.target.value)}
                  className="px-3 py-2 text-sm bg-white border border-gray-300 rounded-lg"
                >
                  <option value="all">
                    All Branches (
                    {branchesWithCount.reduce((s, b) => s + b.count, 0)})
                  </option>
                  {branchesWithCount.map((b) => (
                    <option key={b.name} value={b.name}>
                      {b.name} ({b.count})
                    </option>
                  ))}
                </select>

                <select
                  value={departmentFilter}
                  onChange={(e) => onDepartmentChange(e.target.value)}
                  className="px-3 py-2 text-sm bg-white border border-gray-300 rounded-lg"
                >
                  <option value="all">
                    All Departments (
                    {departmentsWithCount.reduce((s, d) => s + d.count, 0)})
                  </option>
                  {departmentsWithCount.map((d) => (
                    <option key={d.name} value={d.name}>
                      {d.name} ({d.count})
                    </option>
                  ))}
                </select>

                <select
                  value={positionFilter}
                  onChange={(e) => onPositionChange(e.target.value)}
                  className="px-3 py-2 text-sm bg-white border border-gray-300 rounded-lg"
                >
                  <option value="all">
                    All Positions (
                    {positionsWithCount.reduce((s, p) => s + p.count, 0)})
                  </option>
                  {positionsWithCount.map((p) => (
                    <option key={p.name} value={p.name}>
                      {p.name} ({p.count})
                    </option>
                  ))}
                </select>

                <button
                  type="button"
                  onClick={clearAllFilters}
                  title="Clear all filters"
                  className="px-2 py-1 text-sm bg-white border rounded-md hover:bg-blue-50"
                >
                  Clear
                </button>
              </div>
            </div>

            <div className="hidden sm:flex sm:items-center sm:gap-2">
              <div className="flex items-center gap-2">
                {!permLoading && permissions?.can_add && (
                  <Tooltip title="Add Employee" placement="bottom">
                    <button
                      className="flex items-center justify-center w-10 h-10 text-white bg-blue-600 rounded-lg"
                      onClick={() => {
                        setEditingEmployee(null);
                        setIsModalOpen(true);
                      }}
                      aria-label="Add employee"
                    >
                      <Plus size={18} />
                    </button>
                  </Tooltip>
                )}

                {!permLoading && permissions?.can_delete && (
                  <Tooltip title="Delete Selected Employees" placement="bottom">
                    <button
                      className="flex items-center justify-center w-10 h-10 border rounded-lg hover:bg-red-600 hover:text-white hover:border-red-600"
                      onClick={handleDeleteSelectedEmployees}
                    >
                      <Trash2 size={18} />
                    </button>
                  </Tooltip>
                )}

                {!permLoading && permissions?.can_print && (
                  <Tooltip title="Print Selected" placement="bottom">
                    <button
                      className="flex items-center justify-center w-10 h-10 border rounded-lg hover:bg-blue-50 hover:text-blue-600 hover:border-blue-200 transition-colors"
                      onClick={handlePrintSelected}
                    >
                      <Printer size={18} />
                    </button>
                  </Tooltip>
                )}

                {!permLoading && permissions?.can_edit && (
                  <Tooltip
                    title={`Bulk Settings (${selectedEmployees.length} selected)`}
                    placement="bottom"
                  >
                    <button
                      className={`flex items-center justify-center w-10 h-10 border rounded-lg ${selectedEmployees.length > 0
                          ? "text-blue-700 bg-blue-50 border-blue-200"
                          : "text-gray-600 hover:bg-gray-50"
                        }`}
                      onClick={handleOpenBulkSettings}
                      aria-label="Bulk employee settings"
                    >
                      <Settings size={18} />
                    </button>
                  </Tooltip>
                )}
              </div>

              <div className="flex items-center gap-1 pl-3 ml-2 border-l">
                <Tooltip title="List View">
                  <button
                    onClick={handleListView}
                    className={`w-10 h-10 flex items-center justify-center rounded-lg ${activeView === "list" ? "bg-blue-100" : "hover:bg-gray-100"}`}
                    aria-pressed={activeView === "list"}
                  >
                    <AlignJustify size={18} />
                  </button>
                </Tooltip>

                <Tooltip title="Grid View">
                  <button
                    onClick={handleGridView}
                    className={`w-10 h-10 flex items-center justify-center rounded-lg ${activeView === "grid" ? "bg-blue-100" : "hover:bg-gray-100"}`}
                    aria-pressed={activeView === "grid"}
                  >
                    <Grid3x3 size={18} />
                  </button>
                </Tooltip>
              </div>
            </div>

            <div className="flex items-center gap-2 sm:hidden">
              <button
                onClick={() => {
                  setMobileActionsOpen((s) => !s);
                  setMobileFiltersOpen(false);
                }}
                className="flex items-center justify-center w-10 h-10 bg-white border rounded-lg"
                aria-expanded={mobileActionsOpen}
                aria-controls="mobile-actions-panel"
                aria-label="Open actions"
              >
                <AlignJustify size={18} />
              </button>

              <button
                onClick={() => {
                  setMobileFiltersOpen((s) => !s);
                  setMobileActionsOpen(false);
                }}
                className="flex items-center justify-center w-10 h-10 bg-white border rounded-lg"
                aria-expanded={mobileFiltersOpen}
                aria-controls="mobile-filters"
                aria-label="Open filters"
              >
                <svg
                  className="w-5 h-5"
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth="2"
                    d="M22 3H2l8 9v7l4 2v-9l8-9z"
                  />
                </svg>
              </button>
            </div>
          </div>
        </div>

        {(isListRefreshing || isLoadingLookups || refreshNotice || error) && (
          <div className="flex flex-wrap items-center gap-3 mt-3 text-xs">
            {isListRefreshing && (
              <span className="inline-flex items-center gap-2 text-blue-700">
                <span className="w-3 h-3 border-2 border-blue-200 border-t-blue-600 rounded-full animate-spin" />
                Refreshing employees...
              </span>
            )}
            {isLoadingLookups && (
              <span className="text-slate-500">Loading filters...</span>
            )}
            {refreshNotice && (
              <span className="px-2 py-1 text-amber-700 bg-amber-50 border border-amber-200 rounded-md">
                {refreshNotice}
              </span>
            )}
            {error && (
              <span className="px-2 py-1 text-red-700 bg-red-50 border border-red-200 rounded-md">
                {error}
              </span>
            )}
          </div>
        )}

        <div
          id="mobile-actions-panel"
          className={`${mobileActionsOpen ? "max-h-[340px] opacity-100" : "max-h-0 opacity-0"} overflow-hidden transition-all duration-200 mt-3 sm:hidden`}
        >
          <div className="flex flex-col gap-3 p-3 bg-white border rounded-lg">
            <div className="flex gap-2">
              {!permLoading && permissions?.can_add && (
                <button
                  className="flex-1 px-3 py-2 text-sm text-white bg-blue-600 rounded-lg"
                  onClick={() => {
                    setEditingEmployee(null);
                    setIsModalOpen(true);
                    setMobileActionsOpen(false);
                  }}
                >
                  Add
                </button>
              )}
              {!permLoading && permissions?.can_delete && (
                <button
                  className="flex-1 px-3 py-2 text-sm border rounded-lg hover:bg-red-600 hover:text-white hover:border-red-600"
                  onClick={() => {
                    handleDeleteSelectedEmployees();
                    setMobileActionsOpen(false);
                  }}
                >
                  Delete
                </button>
              )}
            </div>

            <div className="flex gap-2">
              {!permLoading && permissions?.can_print && (
                <button
                  className="flex-1 px-3 py-2 text-sm border rounded-lg hover:bg-blue-50 hover:text-blue-600 hover:border-blue-200 transition-colors"
                  onClick={() => {
                    handlePrintSelected();
                    setMobileActionsOpen(false);
                  }}
                >
                  Print
                </button>
              )}

              {!permLoading && permissions?.can_edit && (
                <button
                  className="flex-1 px-3 py-2 text-sm border rounded-lg"
                  onClick={() => {
                    handleOpenBulkSettings();
                    setMobileActionsOpen(false);
                  }}
                >
                  Settings
                </button>
              )}

              <button
                onClick={handleListView}
                className={`flex-1 px-3 py-2 text-sm rounded-lg ${activeView === "list" ? "bg-blue-100" : "border"}`}
              >
                List
              </button>
              <button
                onClick={handleGridView}
                className={`flex-1 px-3 py-2 text-sm rounded-lg ${activeView === "grid" ? "bg-blue-100" : "border"}`}
              >
                Grid
              </button>
            </div>
          </div>
        </div>

        <div
          id="mobile-filters"
          className={`${mobileFiltersOpen ? "max-h-[500px] opacity-100" : "max-h-0 opacity-0"} overflow-hidden transition-all duration-200 mt-3 sm:hidden`}
        >
          <div className="flex flex-col gap-3 p-3 bg-white border rounded-lg">
            <select
              value={statusFilter}
              onChange={(e) => setStatusFilter(e.target.value)}
              className="w-full px-4 py-2 text-sm bg-white border rounded-lg"
            >
              <option value="all">
                All Status (
                {(statusWithCount.active || 0) +
                  (statusWithCount.inactive || 0)}
                )
              </option>
              <option value="active">
                Active ({statusWithCount.active || 0})
              </option>
              <option value="inactive">
                Inactive ({statusWithCount.inactive || 0})
              </option>
            </select>

            <select
              value={typeFilter}
              onChange={(e) => setTypeFilter(e.target.value)}
              className="w-full px-4 py-2 text-sm bg-white border rounded-lg"
            >
              <option value="all">
                All Types ({typesWithCount.reduce((s, t) => s + t.count, 0)})
              </option>
              {typesWithCount.map((t) => (
                <option key={t.name} value={t.name}>
                  {t.name} ({t.count})
                </option>
              ))}
            </select>

            <div className="flex flex-col gap-2">
              <select
                value={branchFilter}
                onChange={(e) => onBranchChange(e.target.value)}
                className="w-full px-4 py-2 text-sm bg-white border rounded-lg"
              >
                <option value="all">
                  All Branches (
                  {branchesWithCount.reduce((s, b) => s + b.count, 0)})
                </option>
                {branchesWithCount.map((b) => (
                  <option key={b.name} value={b.name}>
                    {b.name} ({b.count})
                  </option>
                ))}
              </select>

              <select
                value={departmentFilter}
                onChange={(e) => onDepartmentChange(e.target.value)}
                className="w-full px-4 py-2 text-sm bg-white border rounded-lg"
              >
                <option value="all">
                  All Departments (
                  {departmentsWithCount.reduce((s, d) => s + d.count, 0)})
                </option>
                {departmentsWithCount.map((d) => (
                  <option key={d.name} value={d.name}>
                    {d.name} ({d.count})
                  </option>
                ))}
              </select>

              <select
                value={positionFilter}
                onChange={(e) => onPositionChange(e.target.value)}
                className="w-full px-4 py-2 text-sm bg-white border rounded-lg"
              >
                <option value="all">
                  All Positions (
                  {positionsWithCount.reduce((s, p) => s + p.count, 0)})
                </option>
                {positionsWithCount.map((p) => (
                  <option key={p.name} value={p.name}>
                    {p.name} ({p.count})
                  </option>
                ))}
              </select>

              <button
                onClick={() => {
                  clearAllFilters();
                  setMobileFiltersOpen(false);
                }}
                className="w-full px-4 py-2 text-sm bg-white border rounded-lg hover:bg-blue-50"
              >
                Clear filters
              </button>
            </div>

            <div className="flex gap-2">
              {!permLoading && permissions?.can_add && (
                <button
                  className="flex-1 px-4 py-2 text-sm text-white bg-blue-600 rounded-lg"
                  onClick={() => {
                    setEditingEmployee(null);
                    setIsModalOpen(true);
                    setMobileFiltersOpen(false);
                  }}
                >
                  Add
                </button>
              )}
              {!permLoading && permissions?.can_delete && (
                <button
                  className="flex-1 px-4 py-2 text-sm border rounded-lg hover:bg-red-600 hover:text-white hover:border-red-600"
                  onClick={() => {
                    handleDeleteSelectedEmployees();
                    setMobileFiltersOpen(false);
                  }}
                >
                  Delete
                </button>
              )}
              {!permLoading && permissions?.can_print && (
                <button
                  className="flex-1 px-4 py-2 text-sm border rounded-lg hover:bg-blue-50 hover:text-blue-600 hover:border-blue-200 transition-colors"
                  onClick={() => {
                    handlePrintSelected();
                    setMobileFiltersOpen(false);
                  }}
                >
                  Print
                </button>
              )}
              {!permLoading && permissions?.can_edit && (
                <button
                  className="flex-1 px-4 py-2 text-sm border rounded-lg"
                  onClick={() => {
                    handleOpenBulkSettings();
                    setMobileFiltersOpen(false);
                  }}
                >
                  Settings
                </button>
              )}
            </div>

            <div className="flex gap-2">
              <button
                onClick={() => {
                  handleListView();
                  setMobileFiltersOpen(false);
                }}
                className={`flex-1 px-4 py-2 text-sm rounded-lg ${activeView === "list" ? "bg-blue-100" : "border"}`}
              >
                List
              </button>
              <button
                onClick={() => {
                  handleGridView();
                  setMobileFiltersOpen(false);
                }}
                className={`flex-1 px-4 py-2 text-sm rounded-lg ${activeView === "grid" ? "bg-blue-100" : "border"}`}
              >
                Grid
              </button>
            </div>
          </div>
        </div>
      </div>

      {activeView === "list" ? (
        <EmployeeListView
          loading={isInitialLoading}
          filteredEmployees={filteredEmployees}
          selectedEmployees={selectedEmployees}
          handleSelectAll={handleSelectAll}
          handleSelectEmployee={handleSelectEmployee}
          handleEditEmployee={handleEditEmployee}
          handleDeleteEmployee={handleDeleteEmployee}
          handleToggleStatus={handleToggleStatus}
          handleReassignEmployee={handleOpenAssignmentModal}
          canManageAssignments={canManageAssignments}
          user={user}
        />
      ) : (
        <div className="flex flex-col gap-4">
          <EmployeeGridView
            loading={isInitialLoading}
            filteredEmployees={paginatedGridEmployees}
            selectedEmployees={selectedEmployees}
            handleSelectAll={handleSelectAll}
            handleSelectEmployee={handleSelectEmployee}
            handleEditEmployee={handleEditEmployee}
            handleDeleteEmployee={handleDeleteEmployee}
            handleToggleStatus={handleToggleStatus}
            handleReassignEmployee={handleOpenAssignmentModal}
            canManageAssignments={canManageAssignments}
            user={user}
          />
          {!isInitialLoading && gridTotalPages > 1 && (
            <div className="flex flex-col sm:flex-row items-center justify-between w-full px-5 py-4 bg-white border border-slate-200/80 rounded-2xl shadow-sm gap-4">
              <p className="text-xs font-medium text-slate-500 text-center sm:text-left">
                Showing{" "}
                <span className="font-bold text-slate-700">
                  {(gridCurrentPage - 1) * gridItemsPerPage + 1}
                </span>{" "}
                to{" "}
                <span className="font-bold text-slate-700">
                  {Math.min(
                    gridCurrentPage * gridItemsPerPage,
                    filteredEmployees.length,
                  )}
                </span>{" "}
                of{" "}
                <span className="font-bold text-slate-700">
                  {filteredEmployees.length}
                </span>{" "}
                employees
              </p>
              <div className="flex items-center gap-1.5 p-1 bg-slate-50 border border-slate-100 rounded-xl shadow-sm">
                <button
                  onClick={() => setGridCurrentPage((p) => Math.max(1, p - 1))}
                  disabled={gridCurrentPage === 1}
                  className="p-1.5 text-slate-400 hover:text-blue-600 hover:bg-white rounded-lg disabled:opacity-50 disabled:hover:bg-transparent transition-all shadow-none hover:shadow-sm"
                >
                  <ChevronLeft size={16} />
                </button>

                {gridPageNumbers.map((p, idx) =>
                  p === "..." ? (
                    <span
                      key={`dots-${idx}`}
                      className="px-1.5 text-slate-300 text-xs font-bold tracking-widest"
                    >
                      ...
                    </span>
                  ) : (
                    <button
                      key={p}
                      onClick={() => setGridCurrentPage(p)}
                      className={`min-w-[32px] h-8 px-2 flex items-center justify-center rounded-lg text-xs font-bold transition-all duration-200 ${gridCurrentPage === p
                          ? "bg-blue-600 text-white shadow-sm shadow-blue-200"
                          : "text-slate-600 hover:bg-white hover:text-blue-600 hover:shadow-sm"
                        }`}
                    >
                      {p}
                    </button>
                  ),
                )}

                <button
                  onClick={() =>
                    setGridCurrentPage((p) => Math.min(gridTotalPages, p + 1))
                  }
                  disabled={gridCurrentPage === gridTotalPages}
                  className="p-1.5 text-slate-400 hover:text-blue-600 hover:bg-white rounded-lg disabled:opacity-50 disabled:hover:bg-transparent transition-all shadow-none hover:shadow-sm"
                >
                  <ChevronRight size={16} />
                </button>
              </div>
            </div>
          )}
        </div>
      )}

      {!isInitialLoading && filteredEmployees.length === 0 && (
        <div className="flex flex-col items-center justify-center p-6 text-gray-500">
          <UserRoundX className="w-10 h-10 mb-2 text-gray-400" />
          <p>No employees found{searchQuery ? ` for "${searchQuery}"` : ""}.</p>
        </div>
      )}

      <EmployeeModal
        isOpen={isModalOpen}
        onClose={() => {
          setIsModalOpen(false);
          setTimeout(() => cleanupBlockingOverlays(), 0);
        }}
        onSubmit={(emp, mode) => handleAddOrUpdateEmployee(emp, mode)}
        employee={editingEmployee}
        onOpenAssign={handleOpenAssign}
        assignmentOptions={assignmentOptions}
        canManageAssignments={canManageAssignments}
        isSaving={isSavingEmployee}
        isLoadingLookups={isLoadingLookups}
      />

      <EmployeeAssignmentModal
        open={isAssignmentModalOpen}
        employee={assignmentModalEmployee}
        assignmentOptions={assignmentOptions}
        currentUser={user}
        onClose={() => {
          setIsAssignmentModalOpen(false);
          setAssignmentModalEmployee(null);
          setTimeout(() => cleanupBlockingOverlays(), 0);
        }}
        onSaved={handleAssignmentSaved}
      />

      <BulkEmployeeActionsModal
        open={isBulkModalOpen}
        selectedCount={selectedEmployees.length}
        applying={bulkApplying}
        onClose={() => setIsBulkModalOpen(false)}
        onApply={handleBulkUpdateEmployees}
      />

      <AssignScheduleModal
        key={assignModalKey}
        open={isAssignModalOpen}
        onClose={() => {
          setIsAssignModalOpen(false);
          setTimeout(() => cleanupBlockingOverlays(), 0);
        }}
        workTimes={workTimes}
        employees={employees}
        initialSelectedEmployees={assignPreselectedEmployees}
        createSchedule={createSchedule}
        updateSchedule={updateSchedule}
        deleteSchedule={deleteSchedule}
        fetchSchedules={fetchSchedules}
        sw={(opts) => Swal.fire(opts)}
      />
    </div>
  );
}

export default Employees;
