import React, { useMemo, useState } from 'react';
import { Property } from '../types';
import { formatDuration, formatAge } from '../lib/format';
import InfoPopup from './InfoPopup';

interface PropertiesPaneProps {
  properties: Property[];
  total: number;
  loading: boolean;
  hexagonId: string | null;
  onLoadMore: () => void;
  onClose: () => void;
  onNavigateToSource?: (slug: string) => void;
  isHoveredPreview?: boolean;
  hoverMode?: boolean;
  onHoverModeChange?: (enabled: boolean) => void;
}

type SortBy = 'price' | 'size' | 'energy';

export function PropertiesPane({
  properties,
  total,
  loading,
  hexagonId,
  onLoadMore,
  onClose,
  onNavigateToSource,
  isHoveredPreview,
  hoverMode,
  onHoverModeChange,
}: PropertiesPaneProps) {
  const [sortBy, setSortBy] = useState<SortBy>('price');
  const [search, setSearch] = useState('');
  const [showInfo, setShowInfo] = useState(false);

  const filteredAndSorted = useMemo(() => {
    const query = search.trim().toLowerCase();
    const filtered = query
      ? properties.filter((p) => {
          const addr = (p.address || '').toLowerCase();
          const pc = (p.postcode || '').toLowerCase();
          return addr.includes(query) || pc.includes(query);
        })
      : properties;
    return [...filtered].sort((a, b) => {
      switch (sortBy) {
        case 'price':
          return ((b.latest_price as number) || 0) - ((a.latest_price as number) || 0);
        case 'size':
          return ((b.total_floor_area as number) || 0) - ((a.total_floor_area as number) || 0);
        case 'energy':
          return (a.current_energy_rating || 'Z').localeCompare(b.current_energy_rating || 'Z');
      }
    });
  }, [properties, sortBy, search]);

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

  return (
    <div className="flex flex-col h-full">
      <div className="p-4 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-lg font-semibold dark:text-warm-100">Properties</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>
            )}
            <button
              onClick={() => setShowInfo(true)}
              className="text-warm-400 hover:text-warm-700 dark:hover:text-warm-300 p-0.5 rounded"
              title="Data source info"
            >
              <svg
                className="w-3.5 h-3.5"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth={2}
              >
                <circle cx="12" cy="12" r="10" />
                <path strokeLinecap="round" d="M12 16v-4m0-4h.01" />
              </svg>
            </button>
          </div>
          <div className="flex items-center gap-1">
            {onHoverModeChange && (
              <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>
        <p className="text-sm text-warm-600 dark:text-warm-400">
          {search.trim()
            ? `${filteredAndSorted.length} match${filteredAndSorted.length !== 1 ? 'es' : ''} in ${properties.length} loaded`
            : `Showing ${properties.length} of ${total} properties`}
        </p>
        {showInfo && (
          <InfoPopup
            title="Property Data"
            onClose={() => setShowInfo(false)}
            sourceLink={
              onNavigateToSource
                ? {
                    label: 'View data source',
                    onClick: () => {
                      onNavigateToSource('epc');
                      setShowInfo(false);
                    },
                  }
                : undefined
            }
          >
            <p className="text-sm text-warm-700 dark:text-warm-300 mb-4 leading-relaxed">
              Property data combines Energy Performance Certificates (EPC) with HM Land Registry
              Price Paid records, fuzzy-matched by address within each postcode. Includes floor
              area, energy ratings, construction age, and tenure from EPC surveys, plus the most
              recent sale price from the Land Registry.
            </p>
          </InfoPopup>
        )}
      </div>

      <div className="p-2 border-b border-warm-200 dark:border-navy-700 space-y-2">
        <input
          type="text"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          placeholder="Search by address or postcode..."
          className="w-full p-2 border border-warm-300 dark:border-navy-700 rounded text-sm bg-white dark:bg-navy-800 dark:text-warm-200 placeholder-warm-400 dark:placeholder-warm-500"
        />
        <select
          value={sortBy}
          onChange={(e) => setSortBy(e.target.value as SortBy)}
          className="w-full p-2 border border-warm-300 dark:border-navy-700 rounded text-sm bg-white dark:bg-navy-800 dark:text-warm-200"
        >
          <option value="price">Price (High to Low)</option>
          <option value="size">Size (Large to Small)</option>
          <option value="energy">Energy Rating (Best to Worst)</option>
        </select>
      </div>

      <div className="flex-1 overflow-y-auto">
        {loading && properties.length === 0 ? (
          <div className="p-4 dark:text-warm-400">Loading...</div>
        ) : (
          <>
            {filteredAndSorted.map((property, idx) => (
              <PropertyCard key={idx} property={property} />
            ))}
            {properties.length < total && (
              <button
                onClick={onLoadMore}
                disabled={loading}
                className="w-full p-4 text-teal-600 dark:text-teal-400 hover:bg-teal-50 dark:hover:bg-teal-900/30 disabled:opacity-50"
              >
                {loading ? 'Loading...' : `Load More (${total - properties.length} remaining)`}
              </button>
            )}
          </>
        )}
      </div>
    </div>
  );
}

function getNum(property: Property, ...keys: string[]): number | undefined {
  for (const key of keys) {
    const v = property[key];
    if (v !== undefined && v !== null && typeof v === 'number') return v;
  }
  return undefined;
}

function PropertyCard({ property }: { property: Property }) {
  const fmt = (value: number | undefined, decimals = 0): string => {
    if (value === undefined) return '';
    return decimals > 0 ? value.toFixed(decimals) : Math.round(value).toLocaleString();
  };

  const price = getNum(property, 'Last known price', 'latest_price');
  const pricePerSqm = getNum(property, 'Price per sqm', 'price_per_sqm');
  const floorArea = getNum(property, 'Total floor area (sqm)', 'total_floor_area');
  const rooms = getNum(
    property,
    'Rooms (including bedrooms & bathrooms)',
    'number_habitable_rooms'
  );
  const age = getNum(property, 'Approximate construction age', 'construction_age_band');
  const councilTax = getNum(property, 'Council tax (£/yr)');
  const councilTaxD = getNum(property, 'Council tax Band D (£/yr)');

  return (
    <div className="p-4 border-b border-warm-100 dark:border-navy-800 hover:bg-warm-50 dark:hover:bg-navy-800">
      <div className="font-semibold dark:text-warm-100">
        {property.address || 'Unknown Address'}
      </div>
      <div className="text-sm text-warm-600 dark:text-warm-400">{property.postcode}</div>

      {price !== undefined && (
        <div className="mt-2 text-lg font-bold text-teal-700 dark:text-teal-400">
          £{fmt(price)}
          {pricePerSqm !== undefined && (
            <span className="text-sm font-normal text-warm-600 dark:text-warm-400">
              {' '}
              (£{fmt(pricePerSqm)}/m²)
            </span>
          )}
        </div>
      )}

      <div className="mt-2 grid grid-cols-2 gap-x-4 gap-y-1 text-sm dark:text-warm-300">
        {property.property_type && (
          <div>
            <span className="text-warm-500 dark:text-warm-400">Type:</span> {property.property_type}
          </div>
        )}
        {property.built_form && (
          <div>
            <span className="text-warm-500 dark:text-warm-400">Built form:</span>{' '}
            {property.built_form}
          </div>
        )}
        {property.duration && (
          <div>
            <span className="text-warm-500 dark:text-warm-400">Tenure:</span>{' '}
            {formatDuration(property.duration)}
          </div>
        )}
        {floorArea !== undefined && (
          <div>
            <span className="text-warm-500 dark:text-warm-400">Floor area:</span> {fmt(floorArea)}m²
          </div>
        )}
        {rooms !== undefined && (
          <div>
            <span className="text-warm-500 dark:text-warm-400">Rooms:</span> {fmt(rooms)}
          </div>
        )}
        {age !== undefined && (
          <div>
            <span className="text-warm-500 dark:text-warm-400">Built:</span>{' '}
            {formatAge(age, property.is_construction_date_approximate ?? true)}
          </div>
        )}
        {property.current_energy_rating && (
          <div>
            <span className="text-warm-500 dark:text-warm-400">EPC rating:</span>{' '}
            {property.current_energy_rating}
          </div>
        )}
        {property.potential_energy_rating && (
          <div>
            <span className="text-warm-500 dark:text-warm-400">EPC potential:</span>{' '}
            {property.potential_energy_rating}
          </div>
        )}
        {councilTax !== undefined ? (
          <div>
            <span className="text-warm-500 dark:text-warm-400">Council tax:</span> £
            {fmt(councilTax)}/yr
          </div>
        ) : councilTaxD !== undefined ? (
          <div>
            <span className="text-warm-500 dark:text-warm-400">Council tax (D):</span> £
            {fmt(councilTaxD)}/yr
          </div>
        ) : null}
      </div>
    </div>
  );
}
