// File Path: monorepo/web/frontend/src/pages/Admin/Speaker/Add/Step1PartBPage.jsx

import React, { useState, useEffect, useCallback, useMemo } from "react";
import { useNavigate, useSearchParams } from "react-router";
import {
  useAuthManager,
  useSpeakerManager,
} from "../../../../services/Services";
import {
  UserPlusIcon,
  WrenchScrewdriverIcon,
  EnvelopeIcon,
  PhoneIcon,
  MapPinIcon,
  BuildingOffice2Icon,
  HomeIcon,
} from "@heroicons/react/24/outline";
import {
  UIXThemeProvider,
  WizardSearchResults,
  Badge,
} from "../../../../components/UIX";
import { useUIXTheme } from "../../../../components/UIX/themes/useUIXTheme.jsx";
import {
  PAGE_SIZE_OPTIONS,
} from "../../../../constants/FieldOptions";
import {
  SPEAKER_STATUS_FILTER_OPTIONS,
  SPEAKER_TYPE_OF_FILTER_OPTIONS,
  SPEAKER_SORT_OPTIONS,
  RESIDENTIAL_SPEAKER_TYPE_OF_ID,
  COMMERCIAL_SPEAKER_TYPE_OF_ID,
} from "../../../../constants/Speaker";

// Configuration for wizard steps - moved outside component
const WIZARD_STEPS = [
  { title: "Search" },
  { title: "Type" },
  { title: "Contact" },
  { title: "Address" },
  { title: "Account" },
  { title: "Metrics" },
  { title: "Comments" },
];

function AdminSpeakerAddStep1PartBPage() {
  const authManager = useAuthManager();
  const speakerManager = useSpeakerManager();
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();

  // URL Parameters
  const firstName = searchParams.get("fn") || "";
  const lastName = searchParams.get("ln") || "";
  const email = searchParams.get("e") || "";
  const phone = searchParams.get("p") || "";

  // Component states
  const [errors, setErrors] = useState({});
  const [speakerList, setSpeakerList] = useState(null);
  const [isLoading, setIsLoading] = useState(true);

  // Pagination state (cursor-based)
  const [pageSize, setPageSize] = useState(25);
  const [previousCursors, setPreviousCursors] = useState([]);
  const [nextCursor, setNextCursor] = useState("");
  const [currentCursor, setCurrentCursor] = useState("");

  // Filter state
  const [sortBy, setSortBy] = useState("lexical_name");
  const [sortOrder, setSortOrder] = useState("ASC");
  const [status, setStatus] = useState("");
  const [type, setType] = useState("");
  const [searchQuery, setSearchQuery] = useState("");
  const [tempSearchQuery, setTempSearchQuery] = useState("");

  // Check authentication
  useEffect(() => {
    if (!authManager.isAuthenticated()) {
      navigate("/login");
      return;
    }
    window.scrollTo(0, 0);
  }, [authManager, navigate]);

  return (
    <UIXThemeProvider>
      <AdminSpeakerAddStep1PartBPageContent
        speakerManager={speakerManager}
        navigate={navigate}
        firstName={firstName}
        lastName={lastName}
        email={email}
        phone={phone}
        errors={errors}
        setErrors={setErrors}
        speakerList={speakerList}
        setSpeakerList={setSpeakerList}
        isLoading={isLoading}
        setIsLoading={setIsLoading}
        pageSize={pageSize}
        setPageSize={setPageSize}
        previousCursors={previousCursors}
        setPreviousCursors={setPreviousCursors}
        nextCursor={nextCursor}
        setNextCursor={setNextCursor}
        currentCursor={currentCursor}
        setCurrentCursor={setCurrentCursor}
        searchQuery={searchQuery}
        setSearchQuery={setSearchQuery}
        tempSearchQuery={tempSearchQuery}
        setTempSearchQuery={setTempSearchQuery}
        sortBy={sortBy}
        setSortBy={setSortBy}
        sortOrder={sortOrder}
        setSortOrder={setSortOrder}
        status={status}
        setStatus={setStatus}
        type={type}
        setType={setType}
      />
    </UIXThemeProvider>
  );
}

function AdminSpeakerAddStep1PartBPageContent({
  speakerManager,
  navigate,
  firstName,
  lastName,
  email,
  phone,
  errors,
  setErrors,
  speakerList,
  setSpeakerList,
  isLoading,
  setIsLoading,
  pageSize,
  setPageSize,
  previousCursors,
  setPreviousCursors,
  nextCursor,
  setNextCursor,
  currentCursor,
  setCurrentCursor,
  searchQuery,
  setSearchQuery,
  tempSearchQuery,
  setTempSearchQuery,
  sortBy,
  setSortBy,
  sortOrder,
  setSortOrder,
  status,
  setStatus,
  type,
  setType,
}) {
  const { getThemeClasses } = useUIXTheme();

  // Handle unauthorized access
  const onUnauthorized = useCallback(() => {
    navigate("/login?unauthorized=true");
  }, [navigate]);

  // Memoize filters map to prevent unnecessary rebuilds
  const filtersMap = useMemo(() => {
    const map = new Map();
    map.set("page_size", pageSize);

    // Add cursor for pagination
    if (currentCursor) {
      map.set("cursor", currentCursor);
    }

    // Add sorting
    map.set("sort_field", sortBy);
    map.set("sort_order", sortOrder);

    // Add filters
    if (status !== "") {
      map.set("status", parseInt(status));
    }
    if (type !== "") {
      map.set("type", parseInt(type));
    }

    // Add search params from URL
    if (firstName) map.set("first_name", firstName);
    if (lastName) map.set("last_name", lastName);
    if (email) map.set("email", email);
    if (phone) map.set("phone", phone);

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

    return map;
  }, [currentCursor, pageSize, sortBy, sortOrder, status, type, searchQuery, firstName, lastName, email, phone]);

  // Fetch speakers with useCallback to prevent infinite loops
  const fetchSpeakerList = useCallback(
    (forceRefresh = false) => {
      setIsLoading(true);
      setErrors({});

      // Use the manager to fetch speakers with force refresh flag
      speakerManager.getSpeakersWithFiltersMapWithCallbacks(
        filtersMap,
        (response) => {
          setSpeakerList(response);

          // Update pagination state
          if (response.hasNextPage) {
            setNextCursor(response.nextCursor);
          } else {
            setNextCursor("");
          }
        },
        (error) => {
          if (import.meta.env.DEV) {
            console.error("Error fetching speaker list:", error);
          }
          setErrors(error);
        },
        () => {
          setIsLoading(false);
        },
        onUnauthorized,
        forceRefresh,
      );
    },
    [filtersMap, speakerManager, onUnauthorized, setIsLoading, setErrors, setSpeakerList, setNextCursor],
  );

  // Get status badge component
  const getStatusBadge = useCallback((speakerStatus) => {
    const variantMap = {
      1: "success", // Active
      2: "secondary", // Archived
    };
    const variant = variantMap[speakerStatus] || "default";
    const label = speakerStatus === 1 ? "Active" : "Archived";

    return (
      <Badge variant={variant} size="sm">
        {label}
      </Badge>
    );
  }, []);

  // Get type badge component
  const getTypeBadge = useCallback((speakerType) => {
    const variantMap = {
      [RESIDENTIAL_SPEAKER_TYPE_OF_ID]: "info",
      [COMMERCIAL_SPEAKER_TYPE_OF_ID]: "warning",
    };
    const labelMap = {
      [RESIDENTIAL_SPEAKER_TYPE_OF_ID]: "Individual",
      [COMMERCIAL_SPEAKER_TYPE_OF_ID]: "Representative",
    };
    const variant = variantMap[speakerType] || "default";
    const label = labelMap[speakerType] || "Unknown";

    return (
      <Badge variant={variant} size="sm">
        {label}
      </Badge>
    );
  }, []);

  // Format phone number
  const formatPhone = useCallback((phone) => {
    if (!phone) return "—";
    const cleaned = phone.replace(/\D/g, "");
    const match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/);
    if (match) {
      return `(${match[1]}) ${match[2]}-${match[3]}`;
    }
    return phone;
  }, []);

  // Column configuration for DataList
  const columns = useMemo(() => [
    {
      header: "Speaker",
      accessor: "firstName",
      type: "text",
      render: (value, speaker) => {
        const displayName = speaker.type === COMMERCIAL_SPEAKER_TYPE_OF_ID
          ? (speaker.organizationName || `${speaker.firstName} ${speaker.lastName}`)
          : `${speaker.firstName} ${speaker.lastName}`;
        return (
          <div className="flex items-center">
            {speaker.type === COMMERCIAL_SPEAKER_TYPE_OF_ID ? (
              <BuildingOffice2Icon className={`w-5 h-5 mr-2 ${getThemeClasses('text-muted')}`} />
            ) : (
              <HomeIcon className={`w-5 h-5 mr-2 ${getThemeClasses('text-muted')}`} />
            )}
            <div>
              <div className="font-medium">{displayName}</div>
              {speaker.type === COMMERCIAL_SPEAKER_TYPE_OF_ID && speaker.organizationName && (
                <div className={`text-sm ${getThemeClasses('text-secondary')}`}>
                  {speaker.firstName} {speaker.lastName}
                </div>
              )}
            </div>
          </div>
        );
      }
    },
    {
      header: "Contact",
      accessor: "email",
      render: (email, speaker) => {
        if (!email && !speaker.phone) return "—";
        return (
          <div className="space-y-1">
            {email && (
              <div className="flex items-center text-sm">
                <EnvelopeIcon className="w-4 h-4 mr-2 text-gray-400" />
                <a
                  href={`mailto:${email}`}
                  className={`transition-colors ${getThemeClasses('link-primary')}`}
                  onClick={(e) => e.stopPropagation()}
                >
                  {email}
                </a>
              </div>
            )}
            {speaker.phone && (
              <div className="flex items-center text-sm">
                <PhoneIcon className="w-4 h-4 mr-2 text-gray-400" />
                <a
                  href={`tel:${speaker.phone}`}
                  className={`transition-colors ${getThemeClasses('link-primary')}`}
                  onClick={(e) => e.stopPropagation()}
                >
                  {formatPhone(speaker.phone)}
                </a>
              </div>
            )}
          </div>
        );
      }
    },
    {
      header: "Location",
      accessor: "city",
      render: (city, speaker) => {
        if (!speaker.addressLine1 && !speaker.city && !speaker.region) return "—";
        return (
          <div className="flex items-center text-sm">
            <MapPinIcon className="w-4 h-4 mr-1 text-gray-400" />
            <div>
              {speaker.addressLine1 && <div>{speaker.addressLine1}</div>}
              {(speaker.city || speaker.region) && (
                <div>
                  {[speaker.city, speaker.region].filter(Boolean).join(", ")}
                </div>
              )}
            </div>
          </div>
        );
      }
    },
    {
      header: "Type",
      accessor: "type",
      render: (type) => getTypeBadge(type)
    },
    {
      header: "Status",
      accessor: "status",
      render: (status) => getStatusBadge(status)
    },
  ], [formatPhone, getTypeBadge, getStatusBadge]); // getThemeClasses removed - captured in closure

  // Pagination handlers
  const handlePageChange = useCallback((direction) => {
    if (direction === "next" && nextCursor) {
      const newPreviousCursors = [...previousCursors];
      newPreviousCursors.push(currentCursor);
      setPreviousCursors(newPreviousCursors);
      setCurrentCursor(nextCursor);
    } else if (direction === "previous" && previousCursors.length > 0) {
      const newPreviousCursors = [...previousCursors];
      const previousCursor = newPreviousCursors.pop();
      setPreviousCursors(newPreviousCursors);
      setCurrentCursor(previousCursor);
    }
  }, [nextCursor, previousCursors, currentCursor, setPreviousCursors, setCurrentCursor]);

  // Search handler
  const handleSearch = useCallback(() => {
    setSearchQuery(tempSearchQuery);
    // Reset pagination when search changes
    setPreviousCursors([]);
    setCurrentCursor("");
    setNextCursor("");
  }, [tempSearchQuery, setSearchQuery, setPreviousCursors, setCurrentCursor, setNextCursor]);

  // Filter change handlers
  const handleSortChange = useCallback((value) => {
    const [field, order] = value.split(",");
    setSortBy(field);
    setSortOrder(order);
    // Reset pagination when sort changes
    setPreviousCursors([]);
    setCurrentCursor("");
    setNextCursor("");
  }, [setSortBy, setSortOrder, setPreviousCursors, setCurrentCursor, setNextCursor]);

  const handleStatusChange = useCallback((value) => {
    setStatus(value);
    // Reset pagination when status changes
    setPreviousCursors([]);
    setCurrentCursor("");
    setNextCursor("");
  }, [setStatus, setPreviousCursors, setCurrentCursor, setNextCursor]);

  const handleTypeChange = useCallback((value) => {
    setType(value);
    // Reset pagination when type changes
    setPreviousCursors([]);
    setCurrentCursor("");
    setNextCursor("");
  }, [setType, setPreviousCursors, setCurrentCursor, setNextCursor]);

  const handlePageSizeChange = useCallback((value) => {
    setPageSize(value);
    // Reset pagination when page size changes
    setPreviousCursors([]);
    setCurrentCursor("");
    setNextCursor("");
  }, [setPageSize, setPreviousCursors, setCurrentCursor, setNextCursor]);

  // Clear filters
  const handleClearFilters = useCallback(() => {
    setSortBy("lexical_name");
    setSortOrder("ASC");
    setStatus("");
    setType("");
    setSearchQuery("");
    setTempSearchQuery("");
    setPreviousCursors([]);
    setCurrentCursor("");
    setNextCursor("");
  }, [setSortBy, setSortOrder, setStatus, setType, setSearchQuery, setTempSearchQuery, setPreviousCursors, setCurrentCursor, setNextCursor]);

  // Memoize search filter configuration to prevent unnecessary re-renders
  const searchFilterConfig = useMemo(() => ({
    searchTerm: searchQuery,
    tempSearchTerm: tempSearchQuery,
    onSearchTermChange: setTempSearchQuery,
    onSearch: handleSearch,
    searchPlaceholder: "Search speakers by name...",
    statusOptions: SPEAKER_STATUS_FILTER_OPTIONS.map(opt => ({
      value: opt.value.toString(),
      label: opt.label
    })),
    statusFilter: status,
    onStatusFilterChange: handleStatusChange,
    typeOptions: SPEAKER_TYPE_OF_FILTER_OPTIONS.map(opt => ({
      value: opt.value.toString(),
      label: opt.label
    })),
    typeFilter: type,
    onTypeFilterChange: handleTypeChange,
    sortOptions: SPEAKER_SORT_OPTIONS,
    sortValue: `${sortBy},${sortOrder}`,
    onSortChange: handleSortChange,
    pageSizeOptions: PAGE_SIZE_OPTIONS.map(opt => ({
      value: opt.value,
      label: opt.label
    })),
    pageSize,
    onPageSizeChange: handlePageSizeChange,
    onClearFilters: handleClearFilters,
    onRefresh: () => fetchSpeakerList(true)
  }), [searchQuery, tempSearchQuery, status, type, sortBy, sortOrder, pageSize, handleSearch, handleStatusChange, handleTypeChange, handleSortChange, handlePageSizeChange, handleClearFilters, fetchSpeakerList, setTempSearchQuery]);

  // Memoize pagination configuration to prevent unnecessary re-renders
  const paginationConfig = useMemo(() => ({
    currentPage: previousCursors.length + 1,
    totalCount: speakerList?.count || 0,
    hasNextPage: !!nextCursor,
    onPageChange: (direction) => {
      if (direction > previousCursors.length + 1) {
        handlePageChange("next");
      } else {
        handlePageChange("previous");
      }
    }
  }), [previousCursors.length, speakerList?.count, nextCursor, handlePageChange]);

  // Action handlers
  const handleSearchAgain = useCallback(() => {
    navigate("/admin/speakers/add/step-1-search");
  }, [navigate]);

  const handleAddNew = useCallback(() => {
    // Clear any existing speaker creation state
    sessionStorage.removeItem("FLASHPOINTTRAINING_SPEAKER_CREATION_STATE");
    navigate("/admin/speakers/add/step-2");
  }, [navigate]);

  // Initial load effect
  useEffect(() => {
    fetchSpeakerList(true);
  }, []);

  // Effect for filter changes and pagination
  useEffect(() => {
    if (searchQuery || currentCursor) {
      fetchSpeakerList(true);
    }
  }, [
    currentCursor,
    pageSize,
    sortBy,
    sortOrder,
    status,
    type,
    searchQuery,
  ]);

  return (
    <WizardSearchResults
      wizardSteps={WIZARD_STEPS}
      currentStep={1}
      wizardTitle="Add New Speaker"
      wizardIcon={WrenchScrewdriverIcon}
      data={speakerList?.results || []}
      columns={columns}
      isLoading={isLoading}
      errors={errors}
      searchFilter={searchFilterConfig}
      pagination={paginationConfig}
      onSearchAgain={handleSearchAgain}
      onAddNew={handleAddNew}
      entityName="speaker"
      emptyState={{
        icon: WrenchScrewdriverIcon,
        title: "No Speakers Found",
        description: "No speakers match your search criteria. Try adjusting your search terms or create a new speaker.",
        isCreateAction: true,
      }}
    />
  );
}

export default AdminSpeakerAddStep1PartBPage;
