import { memo, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import type { FeatureFilters, FeatureMeta } from '../../types';
import { formatValue } from '../../lib/format';
import { ts } from '../../i18n/server';
import { SCHOOL_FILTER_NAME, getSchoolBackendFeatureName } from '../../lib/school-filter';
import { getSpecificCrimeFeatureName } from '../../lib/crime-filter';
import { getElectionVoteShareFeatureName } from '../../lib/election-filter';
import { getEthnicityFeatureName } from '../../lib/ethnicity-filter';
import {
  POI_DISTANCE_FILTER_NAME,
  getPoiDistanceFeatureName,
  getPoiFilterName,
} from '../../lib/poi-distance-filter';

interface HoverCardData {
  count: number;
  [key: string]: string | number | [number, number] | null;
}

interface HoverCardProps {
  x: number;
  y: number;
  id: string;
  isPostcode: boolean;
  data: HoverCardData | null;
  filters: FeatureFilters;
  features: FeatureMeta[];
}

export default memo(function HoverCard({
  x,
  y,
  id,
  isPostcode,
  data,
  filters,
  features,
}: HoverCardProps) {
  const { t } = useTranslation();
  const activeFilterNames = Object.keys(filters);

  const featureMap = useMemo(() => new Map(features.map((f) => [f.name, f])), [features]);

  // Get key stats to show from local data (min_<feature> values)
  const getDisplayStats = () => {
    if (!data) return [];

    const results: { name: string; value: string }[] = [];

    // Show stats for active filters (up to 4)
    for (const name of activeFilterNames.slice(0, 4)) {
      const schoolBackendName = getSchoolBackendFeatureName(name);
      const specificCrimeFeatureName = getSpecificCrimeFeatureName(name);
      const electionVoteShareFeatureName = getElectionVoteShareFeatureName(name);
      const ethnicityFeatureName = getEthnicityFeatureName(name);
      const poiDistanceFeatureName = getPoiDistanceFeatureName(name);
      const backendName =
        schoolBackendName ??
        specificCrimeFeatureName ??
        electionVoteShareFeatureName ??
        ethnicityFeatureName ??
        poiDistanceFeatureName ??
        name;
      const val = data[`avg_${backendName}`] ?? data[`min_${backendName}`];
      if (val == null || typeof val !== 'number') continue;
      const meta = featureMap.get(backendName);
      if (meta?.type === 'enum' && meta.values) {
        const label = meta.values[Math.round(val)];
        if (label) results.push({ name: backendName, value: ts(label) });
      } else {
        results.push({
          name: schoolBackendName
            ? SCHOOL_FILTER_NAME
            : poiDistanceFeatureName
              ? (getPoiFilterName(name) ?? POI_DISTANCE_FILTER_NAME)
              : backendName,
          value: formatValue(val, meta),
        });
      }
    }

    return results;
  };

  const displayStats = getDisplayStats();
  const count = data?.count;

  const cardStyle = {
    left: x,
    top: y - 12,
    transform: 'translate(-50%, -100%)',
  };

  // Loading state: show skeleton when data hasn't arrived yet
  if (!data) {
    return (
      <div
        className="absolute bg-white dark:bg-warm-800 rounded-lg shadow-lg p-3 text-sm pointer-events-none z-30 min-w-[140px]"
        style={cardStyle}
      >
        <div className="animate-pulse space-y-2">
          <div className="h-3.5 w-20 bg-warm-200 dark:bg-warm-600 rounded" />
          <div className="h-2.5 w-14 bg-warm-100 dark:bg-warm-700 rounded" />
        </div>
      </div>
    );
  }

  return (
    <div
      className="absolute bg-white dark:bg-warm-800 rounded-lg shadow-lg p-3 text-sm dark:text-white pointer-events-none z-30 min-w-[180px] max-w-[260px]"
      style={cardStyle}
    >
      <div className="relative">
        {/* Header */}
        <div className="flex items-center justify-between gap-2 mb-1">
          <span className="font-semibold text-navy-950 dark:text-white truncate">
            {isPostcode ? id : t('common.area')}
          </span>
        </div>

        {/* Property count */}
        {count != null && (
          <div className="text-xs text-warm-500 dark:text-warm-300 mb-2">
            {count.toLocaleString()}{' '}
            {count === 1 ? t('common.property') : t('common.propertiesPlural')}
          </div>
        )}

        {/* Quick stats */}
        {displayStats.length > 0 && (
          <div className="space-y-1 border-t border-warm-200 dark:border-warm-700 pt-2">
            {displayStats.map((stat) => (
              <div key={stat.name} className="flex justify-between gap-2 text-xs">
                <span className="text-warm-500 dark:text-warm-300 truncate">{ts(stat.name)}</span>
                <span className="font-medium text-teal-700 dark:text-teal-300 whitespace-nowrap">
                  {stat.value}
                </span>
              </div>
            ))}
          </div>
        )}

        {/* Hint */}
        <div className="text-[10px] text-warm-400 dark:text-warm-500 mt-2 text-center">
          {t('common.clickForDetails')}
        </div>
      </div>
    </div>
  );
});
