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

import React, { useState, useEffect, useRef } from "react";
import {
  ChatBubbleBottomCenterIcon,
  PlusIcon,
  MagnifyingGlassIcon,
  HomeIcon,
  EnvelopeIcon,
  PhoneIcon,
  BuildingOffice2Icon,
  UserCircleIcon,
  ArrowRightCircleIcon,
} from "@heroicons/react/24/outline";
import {
  UniversalListPage,
  ViewButton,
  Badge,
  Card,
  useUIXTheme,
} from "../../../../components/UIX";
import {
  PAGE_SIZE_OPTIONS,
} from "../../../../constants/FieldOptions";
import { useSpeakerManager } from "../../../../services/Services";

// Speaker type constants
const RESIDENTIAL_SPEAKER_TYPE_OF_ID = 2;
const COMMERCIAL_SPEAKER_TYPE_OF_ID = 3;

// Speaker status filter options
const SPEAKER_STATUS_FILTER_OPTIONS = [
  { value: "", label: "All Status" },
  { value: "1", label: "Active" },
  { value: "2", label: "Archived" },
];

// Speaker type filter options
const SPEAKER_TYPE_FILTER_OPTIONS = [
  { value: "", label: "All Types" },
  { value: "0", label: "All" },
  { value: String(RESIDENTIAL_SPEAKER_TYPE_OF_ID), label: "Residential" },
  { value: String(COMMERCIAL_SPEAKER_TYPE_OF_ID), label: "Commercial" },
];

// Speaker sort options
const SPEAKER_SORT_OPTIONS = [
  { value: "lexical_name,ASC", label: "Name (A-Z)" },
  { value: "lexical_name,DESC", label: "Name (Z-A)" },
  { value: "join_date,DESC", label: "Recently Joined" },
  { value: "join_date,ASC", label: "Oldest Joined" },
];

// Speaker type mapping
const SPEAKER_TYPE_MAP = {
  [RESIDENTIAL_SPEAKER_TYPE_OF_ID]: "Residential",
  [COMMERCIAL_SPEAKER_TYPE_OF_ID]: "Commercial",
};

function AdminSpeakerListPage() {
  const speakerManager = useSpeakerManager();
  const { getThemeClasses } = useUIXTheme();

  // State to store speaker details (including levels)
  const [speakerDetails, setSpeakerDetails] = useState({});

  // Ref to track if component is mounted (prevent memory leaks)
  const isMountedRef = useRef(true);

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      isMountedRef.current = false;
    };
  }, []);

  // Get speaker level display text
  const getSpeakerLevelDisplay = (levelValue) => {
    // Simple Level 1/Level 2 system
    if (levelValue === 1) return "Level 1";
    if (levelValue === 2) return "Level 2";
    return null;
  };

  // Fetch speaker details for levels
  const fetchSpeakerDetails = async (speakerIds, onUnauthorized) => {
    const newDetails = {};

    // Fetch details for speakers we don't already have
    const speakersToFetch = speakerIds.filter(id => !speakerDetails[id]);

    if (speakersToFetch.length === 0) return;

    try {
      // Fetch details in parallel for performance
      const detailPromises = speakersToFetch.map(async (speakerId) => {
        try {
          const detail = await speakerManager.getSpeakerDetail(speakerId, onUnauthorized);
          return { id: speakerId, detail };
        } catch (error) {
          if (import.meta.env.DEV) {
            console.warn(`Failed to fetch details for speaker ${speakerId}:`, error);
          }
          return { id: speakerId, detail: null };
        }
      });

      const results = await Promise.all(detailPromises);

      results.forEach(({ id, detail }) => {
        if (detail) {
          newDetails[id] = detail;
        }
      });

      // Update speaker details state only if component is still mounted
      if (isMountedRef.current) {
        setSpeakerDetails(prev => ({ ...prev, ...newDetails }));
      }
    } catch (error) {
      if (import.meta.env.DEV) {
        console.error('Error fetching speaker details:', error);
      }
    }
  };

  // Format speaker type for display
  const getSpeakerTypeDisplay = (type) => {
    return SPEAKER_TYPE_MAP[type] || "Unknown";
  };

  // Get badge component for speaker type
  const getTypeBadge = (speakerType) => {
    const variantMap = {
      [COMMERCIAL_SPEAKER_TYPE_OF_ID]: "primary",
      [RESIDENTIAL_SPEAKER_TYPE_OF_ID]: "secondary",
    };
    const variant = variantMap[speakerType] || "default";

    return (
      <Badge variant={variant} size="sm">
        {getSpeakerTypeDisplay(speakerType)}
      </Badge>
    );
  };

  // Get badge component for job seeker status
  const getJobSeekerBadge = (isJobSeeker) => {
    return (
      <Badge variant={isJobSeeker === 1 ? "success" : "default"} size="sm">
        {isJobSeeker === 1 ? "Yes" : "No"}
      </Badge>
    );
  };

  // Build params function for the API
  const buildParams = (params) => {
    const {
      pageSize = 25,
      currentCursor,
      sortBy,
      sortOrder,
      status,
      type,
      searchQuery,
    } = params || {};

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

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

    // Add sorting
    if (sortBy && sortOrder) {
      const [sortField, sortOrder2] = `${sortBy},${sortOrder}`.split(",");
      filtersMap.set("sort_field", sortField);
      filtersMap.set("sort_order", sortOrder2 === "DESC" ? "-1" : "1");
    }

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

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

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

    return filtersMap;
  };

  // Fetch data function
  const fetchData = async (params, onUnauthorized, forceRefresh) => {
    const filtersMap = buildParams(params);
    return new Promise((resolve, reject) => {
      speakerManager.getSpeakersWithFiltersMap(
        filtersMap,
        onUnauthorized,
        forceRefresh,
      ).then(async (response) => {
        const speakers = response.results || [];

        // Fetch speaker details for levels (in background)
        if (speakers.length > 0) {
          const speakerIds = speakers.map(speaker => speaker.id);
          // Don't await this - fetch details in background
          fetchSpeakerDetails(speakerIds, onUnauthorized);
        }

        resolve({
          results: speakers,
          count: response.count || 0,
          nextCursor: response.nextCursor || ""
        });
      }).catch(reject);
    });
  };

  // Custom grid item renderer
  const renderGridItem = (speaker, navigate) => {
    return (
      <div
        key={speaker.id}
        className={`${getThemeClasses('bg-card')} border ${getThemeClasses('card-border')} rounded-lg shadow-sm hover:shadow-lg transition-shadow cursor-pointer`}
        onClick={() => navigate(`/admin/speaker/${speaker.id}`)}
      >
        <div className="p-6">
          <div className="mb-4">
            <h3 className={`text-lg font-semibold ${getThemeClasses('text-primary')} flex items-start`}>
              <UserCircleIcon className={`w-6 h-6 mr-2 flex-shrink-0 mt-0.5 ${getThemeClasses('text-muted')}`} />
              <span>
                {speaker.type === COMMERCIAL_SPEAKER_TYPE_OF_ID
                  ? speaker.organizationName || `${speaker.firstName} ${speaker.lastName}`
                  : `${speaker.firstName} ${speaker.lastName}`}
              </span>
            </h3>
            {speaker.type === COMMERCIAL_SPEAKER_TYPE_OF_ID && speaker.organizationName && (
              <p className={`text-sm ${getThemeClasses('text-secondary')} mt-1 ml-8`}>
                Contact: {speaker.firstName} {speaker.lastName}
              </p>
            )}
            {/* Speaker Level Display */}
            {(() => {
              // Try to get level from speaker details first, then fallback to speaker object
              const speakerDetail = speakerDetails[speaker.id];
              const levelValue = speakerDetail?.level || speakerDetail?.speakerLevel || speakerDetail?.experienceLevel ||
                                speaker.level || speaker.speakerLevel || speaker.experienceLevel || speaker.proficiencyLevel;
              const levelDisplay = levelValue ? getSpeakerLevelDisplay(levelValue) : null;

              if (levelDisplay) {
                return (
                  <p className={`text-sm ${getThemeClasses('text-secondary')} mt-1 ml-8 font-medium`}>
                    {levelDisplay}
                  </p>
                );
              }
              return null;
            })()}
            {/* Skill Sets Display */}
            {speaker.skillSets && speaker.skillSets.length > 0 && (
              <div className="flex items-start mt-2">
                <ArrowRightCircleIcon className={`w-4 h-4 mr-2 ${getThemeClasses('text-muted')} flex-shrink-0 mt-0.5`} />
                <div className="flex flex-wrap gap-1">
                  {speaker.skillSets.slice(0, 3).map((skill) => (
                    <Badge key={skill.id} variant="primary" size="xs">
                      {skill.subCategory}
                    </Badge>
                  ))}
                  {speaker.skillSets.length > 3 && (
                    <span className={`text-xs ${getThemeClasses('text-muted')}`}>
                      +{speaker.skillSets.length - 3} more
                    </span>
                  )}
                </div>
              </div>
            )}
          </div>

          <div className={`space-y-2 text-base ${getThemeClasses('text-primary')} mb-4`}>
            {speaker.email && (
              <div className="flex items-center text-sm">
                <EnvelopeIcon className={`w-5 h-5 mr-2 ${getThemeClasses('text-muted')}`} />
                <span className={`${getThemeClasses('link-primary')} truncate`}>
                  {speaker.email}
                </span>
              </div>
            )}
            {speaker.phone && (
              <div className="flex items-center text-sm">
                <PhoneIcon className={`w-5 h-5 mr-2 ${getThemeClasses('text-muted')}`} />
                <span>{speaker.phone}</span>
              </div>
            )}
          </div>

          {/* Action buttons */}
          <div className="flex gap-2">
            <ViewButton
              to={`/admin/speaker/${speaker.id}`}
              text="View Details"
              fullWidth={true}
            />
          </div>
        </div>
      </div>
    );
  };

  // Column configuration for DataList
  const columns = [
    {
      header: "Name",
      accessor: "name",
      type: "link",
      linkPath: "/admin/speaker/:id",
      render: (value, speaker) => {
        const displayName = speaker.type === COMMERCIAL_SPEAKER_TYPE_OF_ID
          ? speaker.organizationName || `${speaker.firstName} ${speaker.lastName}`
          : `${speaker.firstName} ${speaker.lastName}`;
        return displayName;
      }
    },
    {
      header: "Contact",
      accessor: "email",
      render: (email, speaker) => {
        if (!email && !speaker.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 ${getThemeClasses('text-muted')}`} />
                <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 ${getThemeClasses('text-muted')}`} />
                <span>{speaker.phone}</span>
              </div>
            )}
          </div>
        );
      }
    },
    {
      header: "Level",
      accessor: "level",
      render: (value, speaker) => {
        // Try to get level from speaker details first, then fallback to speaker object
        const speakerDetail = speakerDetails[speaker.id];
        const levelValue = speakerDetail?.level || speakerDetail?.speakerLevel || speakerDetail?.experienceLevel ||
                          speaker.level || speaker.speakerLevel || speaker.experienceLevel || speaker.proficiencyLevel;
        const levelDisplay = levelValue ? getSpeakerLevelDisplay(levelValue) : null;

        return levelDisplay ? (
          <span className={`text-sm ${getThemeClasses('text-secondary')} font-medium`}>
            {levelDisplay}
          </span>
        ) : (
          <span className={`text-sm ${getThemeClasses('text-muted')} italic`}>—</span>
        );
      }
    },
    {
      header: "Skill Sets",
      accessor: "skillSets",
      render: (skillSets, speaker) => {
        if (!speaker.skillSets || speaker.skillSets.length === 0) {
          return <span className={`text-sm ${getThemeClasses('text-muted')} italic`}>—</span>;
        }

        return (
          <div className="flex flex-wrap gap-1">
            {speaker.skillSets.slice(0, 2).map((skill) => (
              <Badge key={skill.id} variant="primary" size="xs">
                {skill.subCategory}
              </Badge>
            ))}
            {speaker.skillSets.length > 2 && (
              <span className={`text-xs ${getThemeClasses('text-muted')}`}>
                +{speaker.skillSets.length - 2} more
              </span>
            )}
          </div>
        );
      }
    },
    {
      header: "Actions",
      align: "right",
      render: (value, speaker) => (
        <ViewButton
          to={`/admin/speaker/${speaker.id}`}
          text="View Speaker"
        />
      )
    }
  ];

  // UniversalListPage configuration
  const config = {
    entityName: "Speaker",
    entityNamePlural: "Speakers",
    icon: ChatBubbleBottomCenterIcon,
    searchIcon: MagnifyingGlassIcon,
    createIcon: PlusIcon,
    createLabel: "Create Speaker",
    routes: {
      search: "/admin/speakers/search",
      create: "/admin/speakers/add/step-1-search",
      detail: "/admin/speaker/:id",
    },
    breadcrumbItems: [
      {
        label: 'Dashboard',
        to: '/admin/dashboard',
        icon: HomeIcon
      },
      {
        label: 'Speakers',
        icon: ChatBubbleBottomCenterIcon,
        isActive: true
      }
    ],
    columns,
    statusOptions: SPEAKER_STATUS_FILTER_OPTIONS.map(opt => ({
      value: opt.value.toString(),
      label: opt.label
    })),
    typeOptions: SPEAKER_TYPE_FILTER_OPTIONS.map(opt => ({
      value: opt.value === "" ? "0" : opt.value,
      label: opt.label
    })),
    sortOptions: SPEAKER_SORT_OPTIONS,
    pageSizeOptions: PAGE_SIZE_OPTIONS.map(opt => ({
      value: opt.value,
      label: opt.label
    })),
    searchPlaceholder: "Search speakers by name, email, or phone...",
    emptyState: {
      title: "No Speakers Found",
      filterDescription: "No speakers match your current filters. Try adjusting your search criteria.",
      emptyDescription: "No speakers have been added yet.",
      actionLabel: "Add Speaker"
    },
    fetchData,
    buildParams,
    renderGridItem,
    defaultStatus: "1",
    defaultType: "0",
    defaultSort: "lexical_name",
    defaultSortOrder: "ASC",
    defaultPageSize: 25,
    defaultViewType: "grid"
  };

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

export default AdminSpeakerListPage;