import { useMemo } from 'react';
import type { FeatureFilters, FeatureMeta, HexagonStatsResponse } from '../types';
import type { HexagonLocation } from '../lib/external-search';
import { formatValue } from '../lib/format';
import { DualHistogram, LoadingSkeleton } from './DualHistogram';
import EnumBarChart from './EnumBarChart';
import ExternalSearchLinks from './ExternalSearchLinks';

interface AreaPaneProps {
  stats: HexagonStatsResponse | null;
  globalFeatures: FeatureMeta[];
  loading: boolean;
  hexagonId: string | null;
  isHoveredPreview: boolean;
  hoverMode: boolean;
  onHoverModeChange: (enabled: boolean) => void;
  onViewProperties: () => void;
  onClose: () => void;
  hexagonLocation: HexagonLocation | null;
  filters: FeatureFilters;
}

function groupFeatures(globalFeatures: FeatureMeta[]): { name: string; features: FeatureMeta[] }[] {
  const groups: { name: string; features: FeatureMeta[] }[] = [];
  const seen = new Set<string>();
  for (const feature of globalFeatures) {
    const groupName = feature.group || 'Other';
    if (!seen.has(groupName)) {
      seen.add(groupName);
      groups.push({ name: groupName, features: [] });
    }
    groups.find((group) => group.name === groupName)!.features.push(feature);
  }
  return groups;
}

export default function AreaPane({
  stats,
  globalFeatures,
  loading,
  hexagonId,
  isHoveredPreview,
  hoverMode,
  onHoverModeChange,
  onViewProperties,
  onClose,
  hexagonLocation,
  filters,
}: AreaPaneProps) {
  const featureGroups = useMemo(() => groupFeatures(globalFeatures), [globalFeatures]);

  const numericByName = useMemo(() => {
    if (!stats) return new Map();
    return new Map(stats.numeric_features.map((feature) => [feature.name, feature]));
  }, [stats]);

  const enumByName = useMemo(() => {
    if (!stats) return new Map();
    return new Map(stats.enum_features.map((feature) => [feature.name, feature]));
  }, [stats]);

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

  if (!hexagonId) {
    return (
      <div className="flex items-center justify-center h-full text-warm-500 dark:text-warm-400 px-4 text-center text-sm">
        Click a hexagon to view area statistics
      </div>
    );
  }

  return (
    <div className="flex flex-col h-full">
      <div className="p-3 border-b border-warm-200 dark:border-navy-700">
        <div className="flex justify-between items-center">
          <div className="flex items-center gap-2">
            <h2 className="text-sm font-semibold dark:text-warm-100">Area Statistics</h2>
            {isHoveredPreview && (
              <span className="text-xs px-1.5 py-0.5 rounded bg-teal-50 dark:bg-teal-900/30 text-teal-600 dark:text-teal-400">
                Preview
              </span>
            )}
          </div>
          <div className="flex items-center gap-1">
            <button
              onClick={() => onHoverModeChange(!hoverMode)}
              className={`p-1 rounded ${
                hoverMode
                  ? 'text-teal-600 dark:text-teal-400 bg-teal-50 dark:bg-teal-900/30'
                  : 'text-warm-400 hover:text-warm-700 dark:hover:text-warm-300'
              }`}
              title={
                hoverMode ? 'Live preview on (click to lock)' : 'Live preview off (click to enable)'
              }
            >
              <svg
                className="w-4 h-4"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth={2}
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
                />
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
                />
              </svg>
            </button>
            <button
              onClick={onClose}
              className="text-warm-400 hover:text-warm-700 dark:hover:text-warm-300 p-1"
            >
              <svg
                className="w-4 h-4"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth={2}
              >
                <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
              </svg>
            </button>
          </div>
        </div>
        {stats && (
          <p className="text-sm text-warm-600 dark:text-warm-400 mt-1">
            {stats.count.toLocaleString()} properties
          </p>
        )}
        {stats && (
          <button
            onClick={onViewProperties}
            className="mt-2 w-full text-sm py-1.5 rounded bg-teal-600 hover:bg-teal-700 text-white font-medium"
          >
            View {stats.count.toLocaleString()} Properties
          </button>
        )}
      </div>

      {hexagonLocation && stats && (
        <ExternalSearchLinks location={hexagonLocation} filters={filters} />
      )}

      <div className="flex-1 overflow-y-auto">
        {loading && !stats ? (
          <LoadingSkeleton />
        ) : stats ? (
          <div className="p-3 space-y-4">
            {featureGroups.map((group) => {
              const hasData = group.features.some(
                (feature) => numericByName.has(feature.name) || enumByName.has(feature.name)
              );
              if (!hasData) return null;

              return (
                <div key={group.name}>
                  <h3 className="text-xs font-semibold text-warm-500 dark:text-warm-400 uppercase tracking-wider mb-2">
                    {group.name}
                  </h3>
                  <div className="space-y-3">
                    {group.features.map((feature) => {
                      const numericStats = numericByName.get(feature.name);
                      const enumStats = enumByName.get(feature.name);

                      if (numericStats) {
                        const globalFeature = globalFeatureByName.get(feature.name);
                        const globalHistogram = globalFeature?.histogram;
                        let globalMean: number | undefined;
                        if (globalHistogram && globalHistogram.counts.length > 0) {
                          const totalCount = globalHistogram.counts.reduce((a, b) => a + b, 0);
                          if (totalCount > 0) {
                            let weightedSum = 0;
                            for (let i = 0; i < globalHistogram.counts.length; i++) {
                              const binCenter =
                                globalHistogram.min + (i + 0.5) * globalHistogram.bin_width;
                              weightedSum += binCenter * globalHistogram.counts[i];
                            }
                            globalMean = weightedSum / totalCount;
                          }
                        }

                        return (
                          <div
                            key={feature.name}
                            className="bg-warm-50 dark:bg-warm-800 rounded p-2"
                          >
                            <div className="flex justify-between items-baseline">
                              <span className="text-xs text-warm-700 dark:text-warm-300 truncate mr-2">
                                {feature.name}
                              </span>
                              <span className="text-xs font-semibold text-teal-700 dark:text-teal-400 whitespace-nowrap">
                                {formatValue(numericStats.mean)}
                              </span>
                            </div>
                            <div className="flex justify-between text-[10px] text-warm-400 dark:text-warm-500 mt-0.5">
                              <span>{formatValue(numericStats.histogram.min)}</span>
                              <span>{formatValue(numericStats.histogram.max)}</span>
                            </div>
                            {globalHistogram ? (
                              <DualHistogram
                                localCounts={numericStats.histogram.counts}
                                globalCounts={globalHistogram.counts}
                                min={numericStats.histogram.min}
                                max={numericStats.histogram.max}
                                globalMean={globalMean}
                              />
                            ) : (
                              <DualHistogram
                                localCounts={numericStats.histogram.counts}
                                globalCounts={numericStats.histogram.counts}
                                min={numericStats.histogram.min}
                                max={numericStats.histogram.max}
                              />
                            )}
                          </div>
                        );
                      }

                      if (enumStats) {
                        return (
                          <div
                            key={feature.name}
                            className="bg-warm-50 dark:bg-warm-800 rounded p-2"
                          >
                            <span className="text-xs text-warm-700 dark:text-warm-300">
                              {feature.name}
                            </span>
                            <EnumBarChart counts={enumStats.counts} />
                          </div>
                        );
                      }

                      return null;
                    })}
                  </div>
                </div>
              );
            })}
          </div>
        ) : null}
      </div>
    </div>
  );
}
