import { useMemo, useState, useCallback } from 'react';
import { Property } from '../../types';
import { formatDuration, formatAge, formatNumber, formatTransactionDate } from '../../lib/format';
import { getNum } from '../../lib/property-fields';
import InfoPopup from '../ui/InfoPopup';
import { SearchInput } from '../ui/SearchInput';
import { EmptyState } from '../ui/EmptyState';
import { InfoIcon } from '../ui/icons';
import { BookmarkIcon } from '../ui/icons/BookmarkIcon';

interface PropertiesPaneProps {
  properties: Property[];
  total: number;
  loading: boolean;
  hexagonId: string | null;
  onLoadMore: () => void;
  onNavigateToSource?: (slug: string) => void;
  onSaveProperty?: (property: Property) => void;
  onUnsaveProperty?: (id: string) => void;
  isPropertySaved?: (address?: string, postcode?: string) => boolean;
  getSavedPropertyId?: (address?: string, postcode?: string) => string | undefined;
}

export function PropertiesPane({
  properties,
  total,
  loading,
  hexagonId,
  onLoadMore,
  onNavigateToSource,
  onSaveProperty,
  onUnsaveProperty,
  isPropertySaved,
  getSavedPropertyId,
}: PropertiesPaneProps) {
  const [search, setSearch] = useState('');
  const [showInfo, setShowInfo] = useState(false);

  const filtered = useMemo(() => {
    const query = search.trim().toLowerCase();
    return query
      ? properties.filter((p) => {
          const addr = (p.address || '').toLowerCase();
          const pc = (p.postcode || '').toLowerCase();
          return addr.includes(query) || pc.includes(query);
        })
      : properties;
  }, [properties, search]);

  if (!hexagonId) {
    return (
      <EmptyState
        icon={<InfoIcon className="w-8 h-8 text-warm-300 dark:text-warm-600" />}
        title="No area selected"
        description="Click a hexagon or postcode to view area statistics"
        centered
      />
    );
  }

  return (
    <div className="h-full overflow-y-auto">
      {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 year, and tenure from EPC surveys, plus the most recent sale price
            from the Land Registry.
          </p>
        </InfoPopup>
      )}

      <div className="p-2">
        <SearchInput
          value={search}
          onChange={setSearch}
          placeholder="Search by address or postcode..."
          className="p-2"
        />
      </div>

      <div>
        {loading && properties.length === 0 ? (
          <PropertyLoadingSkeleton />
        ) : (
          <>
            {filtered.map((property, idx) => (
              <PropertyCard
                key={idx}
                property={property}
                onSave={onSaveProperty}
                onUnsave={onUnsaveProperty}
                isSaved={isPropertySaved?.(property.address, property.postcode)}
                savedId={getSavedPropertyId?.(property.address, property.postcode)}
              />
            ))}
            {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 transition-colors"
              >
                {loading ? (
                  <span className="flex items-center justify-center gap-2">
                    <span className="inline-block w-4 h-4 border-2 border-teal-600 dark:border-teal-400 border-t-transparent rounded-full animate-spin" />
                    Loading...
                  </span>
                ) : (
                  `Load More (${total - properties.length} remaining)`
                )}
              </button>
            )}
          </>
        )}
      </div>
    </div>
  );
}

function PropertyLoadingSkeleton() {
  return (
    <div className="space-y-0">
      {Array.from({ length: 5 }).map((_, idx) => (
        <div key={idx} className="p-4 border-b border-warm-100 dark:border-navy-800 animate-pulse">
          <div className="h-5 w-3/4 bg-warm-200 dark:bg-warm-700 rounded mb-2" />
          <div className="h-4 w-24 bg-warm-200 dark:bg-warm-700 rounded mb-3" />
          <div className="h-6 w-32 bg-warm-200 dark:bg-warm-700 rounded mb-3" />
          <div className="grid grid-cols-2 gap-x-4 gap-y-2">
            {Array.from({ length: 6 }).map((_, i) => (
              <div key={i} className="h-4 bg-warm-200 dark:bg-warm-700 rounded" />
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

function PropertyCard({
  property,
  onSave,
  onUnsave,
  isSaved,
  savedId,
}: {
  property: Property;
  onSave?: (property: Property) => void;
  onUnsave?: (id: string) => void;
  isSaved?: boolean;
  savedId?: string;
}) {
  const handleToggleSave = useCallback(() => {
    if (isSaved && savedId && onUnsave) {
      onUnsave(savedId);
    } else if (onSave) {
      onSave(property);
    }
  }, [isSaved, savedId, onSave, onUnsave, property]);
  const price = getNum(property, 'Last known price');
  const estimatedPrice = getNum(property, 'Estimated current price');
  const pricePerSqm = getNum(property, 'Price per sqm');
  const estPricePerSqm = getNum(property, 'Est. price per sqm');
  const floorArea = getNum(property, 'Total floor area (sqm)');
  const rooms = getNum(property, 'Number of bedrooms & living rooms');
  const age = getNum(property, 'Construction year');
  const transactionDate = getNum(property, 'Date of last transaction');
  const askingPrice = getNum(property, 'Asking price');
  const askingRent = getNum(property, 'Asking rent (monthly)');
  const bedrooms = getNum(property, 'Bedrooms');
  const bathrooms = getNum(property, 'Bathrooms');
  const listingDate = getNum(property, 'Listing date');

  return (
    <div className="p-4 border-b border-warm-100 dark:border-warm-800 hover:bg-warm-50 dark:hover:bg-warm-800">
      <div className="flex items-start justify-between gap-2">
        <div className="min-w-0">
          <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>
        </div>
        {onSave && (
          <button
            onClick={handleToggleSave}
            className={`shrink-0 p-1 rounded ${
              isSaved
                ? 'text-teal-600 dark:text-teal-400'
                : 'text-warm-300 dark:text-warm-600 hover:text-warm-500 dark:hover:text-warm-400'
            }`}
            title={isSaved ? 'Unsave property' : 'Save property'}
          >
            <BookmarkIcon className="w-4 h-4" filled={isSaved} />
          </button>
        )}
      </div>

      {property.property_sub_type && (
        <div className="text-sm text-warm-600 dark:text-warm-400 mt-1">
          {property.property_sub_type}
        </div>
      )}

      {askingPrice !== undefined && (
        <div className="mt-2 text-lg font-bold text-teal-700 dark:text-teal-400">
          {property.price_qualifier && (
            <span className="text-sm font-normal text-warm-500 dark:text-warm-400">
              {property.price_qualifier}{' '}
            </span>
          )}
          £{formatNumber(askingPrice)}
        </div>
      )}

      {askingRent !== undefined && (
        <div className="mt-2 text-lg font-bold text-teal-700 dark:text-teal-400">
          £{formatNumber(askingRent)}
          <span className="text-sm font-normal text-warm-600 dark:text-warm-400">/mo</span>
        </div>
      )}

      {price !== undefined && (
        <div className={`${askingPrice !== undefined || askingRent !== undefined ? '' : 'mt-2 '}text-lg font-bold text-teal-700 dark:text-teal-400`}>
          {askingPrice !== undefined || askingRent !== undefined ? (
            <span className="text-sm font-normal text-warm-600 dark:text-warm-400">
              Last sold: £{formatNumber(price)}
              {transactionDate !== undefined && ` (${formatTransactionDate(transactionDate)})`}
            </span>
          ) : (
            <>
              £{formatNumber(price)}
              {transactionDate !== undefined && (
                <span className="text-sm font-normal text-warm-600 dark:text-warm-400">
                  {' '}
                  ({formatTransactionDate(transactionDate)})
                </span>
              )}
              {pricePerSqm !== undefined && (
                <span className="text-sm font-normal text-warm-600 dark:text-warm-400">
                  {' '}
                  £{formatNumber(pricePerSqm)}/m²
                </span>
              )}
            </>
          )}
        </div>
      )}
      {estimatedPrice !== undefined && (
        <div className="text-sm text-warm-600 dark:text-warm-400">
          Est. value:{' '}
          <span className="font-semibold text-teal-700 dark:text-teal-400">
            £{formatNumber(estimatedPrice)}
          </span>
          {estPricePerSqm !== undefined && (
            <span> (£{formatNumber(estPricePerSqm)}/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>{' '}
            {formatNumber(floorArea)}m²
          </div>
        )}
        {bedrooms !== undefined && (
          <div>
            <span className="text-warm-500 dark:text-warm-400">Bedrooms:</span>{' '}
            {formatNumber(bedrooms)}
          </div>
        )}
        {bathrooms !== undefined && (
          <div>
            <span className="text-warm-500 dark:text-warm-400">Bathrooms:</span>{' '}
            {formatNumber(bathrooms)}
          </div>
        )}
        {rooms !== undefined && (
          <div>
            <span className="text-warm-500 dark:text-warm-400">Rooms:</span> {formatNumber(rooms)}
          </div>
        )}
        {age !== undefined && (
          <div>
            <span className="text-warm-500 dark:text-warm-400">Built:</span>{' '}
            {formatAge(age, property.is_construction_date_approximate)}
          </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>
        )}
        {listingDate !== undefined && (
          <div>
            <span className="text-warm-500 dark:text-warm-400">Listed:</span>{' '}
            {formatTransactionDate(listingDate)}
          </div>
        )}
      </div>

      {property.listing_features && property.listing_features.length > 0 && (
        <div className="mt-2">
          <div className="text-xs text-warm-500 dark:text-warm-400 mb-1">Key features</div>
          <div className="flex flex-wrap gap-1">
            {property.listing_features.map((feature, idx) => (
              <span
                key={idx}
                className="text-xs bg-warm-100 dark:bg-warm-700 text-warm-700 dark:text-warm-300 rounded px-1.5 py-0.5"
              >
                {feature}
              </span>
            ))}
          </div>
        </div>
      )}

      {property.renovation_history && property.renovation_history.length > 0 && (
        <div className="mt-2">
          <div className="text-xs text-warm-500 dark:text-warm-400 mb-1">Renovations</div>
          <div className="flex flex-wrap gap-1">
            {property.renovation_history.map((reno, idx) => (
              <span
                key={idx}
                className="inline-flex items-center gap-1 text-xs bg-warm-100 dark:bg-warm-700 text-warm-700 dark:text-warm-300 rounded px-1.5 py-0.5"
              >
                {reno.event}
                <span className="text-warm-500 dark:text-warm-400">{reno.year}</span>
              </span>
            ))}
          </div>
        </div>
      )}

      {property.listing_url && (
        <div className="mt-2">
          <a
            href={property.listing_url}
            target="_blank"
            rel="noopener noreferrer"
            className="text-xs text-teal-600 dark:text-teal-400 hover:text-teal-800 dark:hover:text-teal-300"
          >
            View external listing &rarr;
          </a>
        </div>
      )}
    </div>
  );
}
