import { LatLngTuple } from 'leaflet';
import React, { useMemo } from 'react';
import { Polyline, Popup } from 'react-leaflet';
import { useOrganizationSites } from '@/hooks/map/useOrganizationSites.ts';
import { Organization, SymbiosisMatch } from '@/types.ts';

interface SymbiosisLinesProps {
  matches: SymbiosisMatch[];
  hoveredOrgId: string | null;
  selectedOrg: Organization;
}

/**
 * Individual symbiosis line component memoized to prevent unnecessary re-renders
 */
const SymbiosisLine = React.memo<{
  match: SymbiosisMatch;
  selectedOrgSite: { Latitude: number; Longitude: number };
  matchOrgSite: { Latitude: number; Longitude: number };
  isHovered: boolean;
}>(({ match, selectedOrgSite, matchOrgSite, isHovered }) => {
  const positions: LatLngTuple[] = useMemo(
    () => [
      [selectedOrgSite.Latitude, selectedOrgSite.Longitude],
      [matchOrgSite.Latitude, matchOrgSite.Longitude],
    ],
    [selectedOrgSite, matchOrgSite]
  );

  return (
    <Polyline
      positions={positions}
      pathOptions={{
        color: 'hsl(var(--primary))',
        weight: isHovered ? 4 : 2,
        opacity: isHovered ? 1 : 0.5,
      }}
    >
      <Popup>
        <div>
          <p className="text-sm">
            {t('symbiosis.connectionTo', { name: match.org?.Name || 'Unknown' })}
          </p>
        </div>
      </Popup>
    </Polyline>
  );
});

SymbiosisLine.displayName = 'SymbiosisLine';

const SymbiosisLines: React.FC<SymbiosisLinesProps> = ({ matches, hoveredOrgId, selectedOrg }) => {
  // Get sites for selected org and matched orgs
  const allOrgs = useMemo(
    () => [selectedOrg, ...matches.map((m) => m.org).filter(Boolean)],
    [selectedOrg, matches]
  );
  const { orgSitesMap } = useOrganizationSites(allOrgs);

  const selectedOrgSite = orgSitesMap.get(selectedOrg.ID);

  // Memoize valid matches with sites to prevent unnecessary recalculations
  const validMatches = useMemo(() => {
    if (!selectedOrgSite) return [];

    return matches
      .map((match) => {
        if (!match.org) return null;

        const matchOrgSite = orgSitesMap.get(match.org.ID);
        if (!matchOrgSite) return null;

        return {
          match,
          matchOrgSite,
        };
      })
      .filter(
        (
          item
        ): item is {
          match: SymbiosisMatch;
          matchOrgSite: NonNullable<typeof item>['matchOrgSite'];
        } => item !== null
      );
  }, [matches, orgSitesMap, selectedOrgSite]);

  if (!selectedOrgSite) return null;

  return (
    <>
      {validMatches.map(({ match, matchOrgSite }) => {
        const isHovered = hoveredOrgId === match.id;

        return (
          <SymbiosisLine
            key={match.id}
            match={match}
            selectedOrgSite={selectedOrgSite}
            matchOrgSite={matchOrgSite}
            isHovered={isHovered}
          />
        );
      })}
    </>
  );
};

export default React.memo(SymbiosisLines);
