// File Path: monorepo/web/frontend/src/pages/Admin/Staff/List/Page.jsx

import React, { useRef, useEffect, useCallback, useMemo, memo } from "react";
import {
  UserGroupIcon,
  PlusIcon,
  MagnifyingGlassIcon,
  HomeIcon,
  EnvelopeIcon,
  PhoneIcon,
  UserCircleIcon,
} from "@heroicons/react/24/outline";
import {
  UniversalListPage,
  ViewButton,
  Badge,
  UIXThemeProvider,
  useUIXTheme,
} from "../../../../components/UIX";
import { PAGE_SIZE_OPTIONS } from "../../../../constants/FieldOptions";
import {
  STAFF_TYPE_FILTER_OPTIONS,
  STAFF_STATUS_FILTER_OPTIONS,
  STAFF_SORT_OPTIONS,
  STAFF_TYPE_MAP,
} from "../../../../constants/Staff";
import { useStaffManager } from "../../../../services/Services";

// Static badge variant mapping
const BADGE_VARIANT_MAP = {
  1: "primary",
  2: "secondary",
  3: "info",
  0: "default",
};

const AdminStaffListPageContent = memo(function AdminStaffListPageContent() {
  const staffManager = useStaffManager();
  const { getThemeClasses } = useUIXTheme();

  // Memoized theme classes
  const themeClasses = useMemo(() => ({
    cardBg: getThemeClasses("bg-card"),
    cardBorder: getThemeClasses("card-border"),
    textPrimary: getThemeClasses("text-primary"),
    textMuted: getThemeClasses("text-muted"),
    linkPrimary: getThemeClasses("link-primary"),
  }), [getThemeClasses]);

  // Track active requests to prevent duplicate calls
  const activeRequestRef = useRef(null);

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      // Cancel any active request when component truly unmounts
      if (activeRequestRef.current) {
        activeRequestRef.current.abort = true;
      }
    };
  }, []);

  // Get badge component for staff type - memoized
  const getTypeBadge = useCallback((staffType) => {
    const variant = BADGE_VARIANT_MAP[staffType] || "default";

    return (
      <Badge variant={variant} size="sm">
        {STAFF_TYPE_MAP[staffType] || "Unknown"}
      </Badge>
    );
  }, []);

  // Build params function for the API
  const buildParams = useCallback((params) => {
    if (import.meta.env.DEV) {
      console.log("Building params with:", params);
    }

    const {
      pageSize = 25,
      currentCursor,
      sortBy,
      sortOrder,
      status,
      type,
      searchQuery,
    } = params || {};

    const filtersMap = new Map();
    filtersMap.set("page_size", String(pageSize));

    if (currentCursor) {
      filtersMap.set("cursor", currentCursor);
    }

    if (sortBy && sortOrder) {
      filtersMap.set("sortField", sortBy);
      filtersMap.set("sortOrder", sortOrder);
    }

    if (status && status !== "0" && status !== "") {
      filtersMap.set("status", parseInt(status));
    }

    if (type && type !== "0" && type !== "") {
      filtersMap.set("type", parseInt(type));
    }

    if (searchQuery && searchQuery.trim()) {
      filtersMap.set("search", searchQuery.trim());
    }

    if (import.meta.env.DEV) {
      console.log("Built filters map:", Array.from(filtersMap.entries()));
    }
    return filtersMap;
  }, []);

  // Fetch data function with better abort handling
  const fetchData = useCallback(
    async (params, onUnauthorized, forceRefresh) => {
      if (import.meta.env.DEV) {
        console.log("fetchData called with params:", params);
      }

      // Cancel any previous request
      if (activeRequestRef.current) {
        activeRequestRef.current.abort = true;
      }

      // Create new request tracker
      const currentRequest = { abort: false };
      activeRequestRef.current = currentRequest;

      const filtersMap = buildParams(params);

      return new Promise((resolve, reject) => {
        // Don't immediately reject if component unmounts - let the request continue
        // This handles React StrictMode's double-invocation

        staffManager.getStaffWithFiltersMapWithCallbacks(
          filtersMap,
          (response) => {
            // Only process if this request hasn't been aborted
            if (!currentRequest.abort) {
              if (import.meta.env.DEV) {
                console.log("Staff list fetch successful:", response);
              }
              // Clear the active request
              if (activeRequestRef.current === currentRequest) {
                activeRequestRef.current = null;
              }
              resolve({
                results: response.results || [],
                count: response.count || 0,
                nextCursor: response.nextCursor || "",
              });
            }
          },
          (error) => {
            // Only process error if this request hasn't been aborted
            if (!currentRequest.abort) {
              if (import.meta.env.DEV) {
                console.error("Staff list fetch error:", error);
              }
              // Clear the active request
              if (activeRequestRef.current === currentRequest) {
                activeRequestRef.current = null;
              }
              reject(error);
            }
          },
          () => {
            if (!currentRequest.abort) {
              if (import.meta.env.DEV) {
                console.log("Staff list fetch done");
              }
            }
          },
          onUnauthorized,
          forceRefresh,
        );
      });
    },
    [buildParams, staffManager],
  );

  // Custom grid item renderer - memoized
  const renderGridItem = useCallback(
    (staff, navigate) => {
      if (import.meta.env.DEV) {
        console.log("Rendering grid item for staff:", staff.id);
      }

      return (
        <div
          key={staff.id}
          className={`${themeClasses.cardBg} border ${themeClasses.cardBorder} rounded-lg shadow-sm hover:shadow-lg transition-shadow cursor-pointer`}
          onClick={() => {
            if (import.meta.env.DEV) {
              console.log(
                "Grid item clicked, navigating to:",
                `/admin/staff/${staff.id}`,
              );
            }
            navigate(`/admin/staff/${staff.id}`);
          }}
        >
          <div className="p-6">
            <div className="mb-4">
              <h3
                className={`text-lg font-semibold ${themeClasses.textPrimary} flex items-start`}
              >
                <UserCircleIcon
                  className={`w-6 h-6 mr-2 flex-shrink-0 mt-0.5 ${themeClasses.textMuted}`}
                />
                <span>
                  {staff.name || `${staff.firstName} ${staff.lastName}`}
                </span>
              </h3>
              {staff.jobTitle && (
                <p
                  className={`text-sm ${themeClasses.textMuted} mt-1 ml-8`}
                >
                  {staff.jobTitle}
                </p>
              )}
              <div className="flex items-center gap-2 mt-2 ml-8">
                {getTypeBadge(staff.type)}
              </div>
            </div>

            <div
              className={`space-y-2 text-base ${themeClasses.textPrimary} mb-4`}
            >
              {staff.email && (
                <div className="flex items-center text-sm">
                  <EnvelopeIcon
                    className={`w-5 h-5 mr-2 ${themeClasses.textMuted}`}
                  />
                  <span
                    className={`${themeClasses.linkPrimary} truncate`}
                  >
                    {staff.email}
                  </span>
                </div>
              )}
              {staff.phone && (
                <div className="flex items-center text-sm">
                  <PhoneIcon
                    className={`w-5 h-5 mr-2 ${themeClasses.textMuted}`}
                  />
                  <span>{staff.phone}</span>
                </div>
              )}
            </div>

            <div className="flex gap-2">
              <ViewButton
                to={`/admin/staff/${staff.id}`}
                text="View Details"
                fullWidth={true}
                onClick={(e) => {
                  if (import.meta.env.DEV) {
                    console.log("ViewButton clicked for staff:", staff.id);
                  }
                  // Don't prevent default - let the button handle navigation
                }}
              />
            </div>
          </div>
        </div>
      );
    },
    [themeClasses, getTypeBadge],
  );

  // Column configuration for DataList view - memoized
  const columns = useMemo(
    () => [
      {
        header: "Name",
        accessor: "name",
        type: "link",
        linkPath: "/admin/staff/:id",
        render: (value, staff) => {
          const displayName =
            staff.name || `${staff.firstName} ${staff.lastName}`;
          if (import.meta.env.DEV) {
            console.log(
              "Rendering name column for staff:",
              staff.id,
              displayName,
            );
          }
          return displayName;
        },
      },
      {
        header: "Contact",
        accessor: "email",
        render: (email, staff) => {
          if (!email && !staff.phone) return null;
          return (
            <div className="space-y-1">
              {email && (
                <div className="flex items-center text-sm">
                  <EnvelopeIcon className={`w-4 h-4 mr-2 ${themeClasses.textMuted}`} />
                  <a
                    href={`mailto:${email}`}
                    className={`transition-colors ${themeClasses.linkPrimary}`}
                    onClick={(e) => e.stopPropagation()}
                  >
                    {email}
                  </a>
                </div>
              )}
              {staff.phone && (
                <div className="flex items-center text-sm">
                  <PhoneIcon className={`w-4 h-4 mr-2 ${themeClasses.textMuted}`} />
                  <span>{staff.phone}</span>
                </div>
              )}
            </div>
          );
        },
      },
      {
        header: "Type",
        accessor: "type",
        render: (type) => getTypeBadge(type),
      },
      {
        header: "Actions",
        align: "right",
        render: (value, staff) => {
          if (import.meta.env.DEV) {
            console.log("Rendering action button for staff:", staff.id);
          }
          return (
            <ViewButton
              to={`/admin/staff/${staff.id}`}
              text="View Staff"
              onClick={() => {
                if (import.meta.env.DEV) {
                  console.log("Action ViewButton clicked for staff:", staff.id);
                }
              }}
            />
          );
        },
      },
    ],
    [themeClasses, getTypeBadge],
  );

  // UniversalListPage configuration - memoized to prevent re-renders
  const config = useMemo(
    () => ({
      entityName: "Staff Member",
      entityNamePlural: "Staff Members",
      icon: UserGroupIcon,
      searchIcon: MagnifyingGlassIcon,
      createIcon: PlusIcon,
      createLabel: "Create Staff Member",
      routes: {
        search: "/admin/staff/search",
        create: "/admin/staff/add/step-1-search",
        detail: "/admin/staff/:id",
      },
      breadcrumbItems: [
        {
          label: "Dashboard",
          to: "/admin/dashboard",
          icon: HomeIcon,
        },
        {
          label: "Staff",
          icon: UserGroupIcon,
          isActive: true,
        },
      ],
      columns,
      statusOptions: STAFF_STATUS_FILTER_OPTIONS.map((opt) => ({
        value: opt.value.toString(),
        label: opt.label,
      })),
      typeOptions: STAFF_TYPE_FILTER_OPTIONS.map((opt) => ({
        value: opt.value === "" ? "0" : opt.value,
        label: opt.label,
      })),
      sortOptions: STAFF_SORT_OPTIONS,
      pageSizeOptions: PAGE_SIZE_OPTIONS.map((opt) => ({
        value: opt.value,
        label: opt.label,
      })),
      searchPlaceholder: "Search staff by name, email, or phone...",
      emptyState: {
        title: "No Staff Members Found",
        filterDescription:
          "No staff members match your current filters. Try adjusting your search criteria.",
        emptyDescription: "No staff members have been added yet.",
        actionLabel: "Add Staff Member",
      },
      fetchData,
      buildParams,
      renderGridItem,
      defaultStatus: "1",
      defaultType: "0",
      defaultSort: "lexical_name",
      defaultSortOrder: "ASC",
      defaultPageSize: 25,
      defaultViewType: "grid",

      // Add debugging callbacks
      onDataLoaded: (data) => {
        if (import.meta.env.DEV) {
          console.log("Data loaded in UniversalListPage:", data);
        }
      },
      onNavigate: (path) => {
        if (import.meta.env.DEV) {
          console.log("UniversalListPage navigating to:", path);
        }
      },
    }),
    [columns, fetchData, buildParams, renderGridItem],
  );

  if (import.meta.env.DEV) {
    console.log("AdminStaffListPage rendering with config:", config);
  }

  return <UniversalListPage config={config} />;
});

AdminStaffListPageContent.displayName = "AdminStaffListPageContent";

function AdminStaffListPage() {
  return (
    <UIXThemeProvider>
      <AdminStaffListPageContent />
    </UIXThemeProvider>
  );
}

export default AdminStaffListPage;
