import L, { LatLngTuple } from 'leaflet';
import React, { useCallback, useMemo } from 'react';
import { Marker, Popup } from 'react-leaflet';
import { getSectorDisplay } from '@/constants.tsx';
import { useMapActions, useMapInteraction } from '@/contexts/MapContexts.tsx';
import { useOrganizationSites } from '@/hooks/map/useOrganizationSites.ts';
import { mapBackendSectorToTranslationKey } from '@/lib/sector-mapper.ts';
import { Organization } from '@/types.ts';
import { getCachedOrganizationIcon } from '@/utils/map/iconCache.ts';

interface OrganizationMarkersProps {
  organizations: Organization[];
  selectedOrg: Organization | null;
  hoveredOrgId: string | null;
}

/**
 * Individual marker component memoized to prevent unnecessary re-renders
 */
const OrganizationMarker = React.memo<{
  org: Organization;
  site: { Latitude: number; Longitude: number };
  sector: { icon?: React.ReactElement; colorKey?: string } | null;
  isSelected: boolean;
  isHovered: boolean;
  onSelect: (org: Organization) => void;
  onHover: (orgId: string | null) => void;
}>(
  ({ org, site, sector, isSelected, isHovered, onSelect, onHover }) => {
    const position: LatLngTuple = useMemo(
      () => [site.Latitude, site.Longitude],
      [site.Latitude, site.Longitude]
    );

    const icon = useMemo(
      () => getCachedOrganizationIcon(org.ID, org, sector, isSelected, isHovered),
      [org.ID, org, sector, isSelected, isHovered]
    );

    const handleClick = useCallback(() => {
      onSelect(org);
    }, [org, onSelect]);

    const handleMouseOver = useCallback(() => {
      onHover(org.ID);
    }, [org.ID, onHover]);

    const handleMouseOut = useCallback(() => {
      onHover(null);
    }, [onHover]);

    // Don't render if coordinates are invalid
    if (!site.Latitude || !site.Longitude || site.Latitude === 0 || site.Longitude === 0) {
      return null;
    }

    return (
      <Marker
        position={position}
        icon={icon}
        zIndexOffset={isSelected ? 1000 : isHovered ? 500 : 0}
        keyboard={true}
        interactive={true}
        riseOnHover={true}
        eventHandlers={{
          click: handleClick,
          mouseover: handleMouseOver,
          mouseout: handleMouseOut,
        }}
      >
        <Popup closeButton={true} autoPan={true} maxWidth={300}>
          <div className="p-1">
            <h3 className="text-base font-semibold mb-1">{org.Name}</h3>
            {org.Sector && <p className="text-sm text-muted-foreground">{org.Sector}</p>}
            {org.Description && (
              <p className="text-xs text-muted-foreground mt-1 line-clamp-2">{org.Description}</p>
            )}
          </div>
        </Popup>
      </Marker>
    );
  },
  (prevProps, nextProps) => {
    // Custom comparison function for React.memo
    return (
      prevProps.org.ID === nextProps.org.ID &&
      prevProps.site.Latitude === nextProps.site.Latitude &&
      prevProps.site.Longitude === nextProps.site.Longitude &&
      prevProps.isSelected === nextProps.isSelected &&
      prevProps.isHovered === nextProps.isHovered &&
      prevProps.sector?.colorKey === nextProps.sector?.colorKey
    );
  }
);

OrganizationMarker.displayName = 'OrganizationMarker';

const OrganizationMarkers: React.FC<OrganizationMarkersProps> = ({
  organizations,
  selectedOrg,
  hoveredOrgId,
}) => {
  const { handleSelectOrg } = useMapActions();
  const { setHoveredOrgId } = useMapInteraction();
  const { orgSitesMap } = useOrganizationSites(organizations);

  // No need for sector map - using getSectorDisplay directly

  // Filter organizations that have valid coordinates (from site or organization)
  const organizationsWithCoordinates = useMemo(() => {
    const result = organizations
      .filter((org) => org.ID && org.ID.trim() !== '')
      .map((org) => {
        const site = orgSitesMap.get(org.ID);

        // Use site coordinates if available and valid
        if (
          site &&
          site.Latitude &&
          site.Longitude &&
          site.Latitude !== 0 &&
          site.Longitude !== 0
        ) {
          return { org, site };
        }

        // Fallback to organization coordinates if available and valid
        if (org.Latitude && org.Longitude && org.Latitude !== 0 && org.Longitude !== 0) {
          return { org, site: { Latitude: org.Latitude, Longitude: org.Longitude } };
        }

        return null;
      })
      .filter(
        (item): item is { org: Organization; site: { Latitude: number; Longitude: number } } =>
          item !== null
      );

    return result;
  }, [organizations, orgSitesMap]);

  // Debug: Log marker count and details in development
  if (process.env.NODE_ENV === 'development') {
    console.log(`[OrganizationMarkers] Rendering ${organizationsWithCoordinates.length} markers`, {
      totalOrganizations: organizations.length,
      withCoordinates: organizationsWithCoordinates.length,
      organizationsSample: organizations.slice(0, 3).map((org) => ({
        id: org.ID,
        name: org.Name,
        coords: [org.Latitude || 0, org.Longitude || 0],
      })),
      sample: organizationsWithCoordinates.slice(0, 3).map(({ org, site }) => ({
        name: org.Name,
        coords: site ? [site.Latitude, site.Longitude] : null,
        hasLogo: !!org.LogoURL,
      })),
    });

    // Additional debug info
    if (organizations.length === 0) {
      console.warn(
        '[OrganizationMarkers] No organizations received! Check API connection and data flow.'
      );
    }
  }

  return (
    <>
      {organizationsWithCoordinates.map(({ org, site }) => {
        const sectorDisplay = getSectorDisplay(org.Sector);

        const isSelected = selectedOrg?.ID === org.ID;
        const isHovered = hoveredOrgId === org.ID;

        // Skip rendering if coordinates are invalid
        if (!site.Latitude || !site.Longitude || site.Latitude === 0 || site.Longitude === 0) {
          return null;
        }

        return (
          <OrganizationMarker
            key={`${org.ID}-${site.Latitude.toFixed(6)}-${site.Longitude.toFixed(6)}`}
            org={org}
            site={site}
            sector={sectorDisplay}
            isSelected={isSelected}
            isHovered={isHovered}
            onSelect={handleSelectOrg}
            onHover={setHoveredOrgId}
          />
        );
      })}
    </>
  );
};

export default React.memo(OrganizationMarkers);
