import React, { useMemo, useState } from 'react';
import { Marker, Popup } from 'react-leaflet';
import { Alert, theme } from 'antd';
import L from 'leaflet';
import type { CanvassAddress, AddressGroup, VisitOutcome } from '@/types/canvass';
import { VISIT_OUTCOME_COLORS, VISIT_OUTCOME_LABELS } from '@/types/canvass';
import { sanitizeHtml } from '@/utils/sanitize';

interface CanvassMarkerGroupProps {
  group: AddressGroup;
  selectedAddressId: string | null;
  onAddressClick: (addressId: string) => void;
}

// Marker size constants
const MARKER_SIZE_DEFAULT = 26;
const MARKER_SIZE_SELECTED = 34;
const MARKER_TOUCH_TARGET = 44;
const MARKER_ANCHOR_OFFSET = 22;

function getMarkerColor(address: CanvassAddress): string {
  if (!address.lastVisit) return '#95a5a6'; // gray — unvisited
  return VISIT_OUTCOME_COLORS[address.lastVisit.outcome] ?? '#95a5a6';
}

function getDominantOutcomeColor(addresses: CanvassAddress[]): string {
  const outcomeCounts: Record<string, number> = {};
  let unvisitedCount = 0;

  for (const addr of addresses) {
    if (addr.lastVisit) {
      const outcome = addr.lastVisit.outcome;
      outcomeCounts[outcome] = (outcomeCounts[outcome] || 0) + 1;
    } else {
      unvisitedCount++;
    }
  }

  // If any are unvisited, show gray
  if (unvisitedCount > 0) return '#95a5a6';

  // Otherwise, find dominant outcome
  let dominant: string | null = null;
  let maxCount = 0;
  for (const [outcome, count] of Object.entries(outcomeCounts)) {
    if (count > maxCount) {
      maxCount = count;
      dominant = outcome;
    }
  }

  return dominant ? VISIT_OUTCOME_COLORS[dominant as VisitOutcome] ?? '#95a5a6' : '#95a5a6';
}

// Inline SVG for house icon
function houseSvg(color: string, size: number, selected: boolean): string {
  return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" role="img" aria-label="Single-family home">
    <title>Single-family home</title>
    ${selected ? `<circle cx="12" cy="12" r="12" fill="none" stroke="white" stroke-width="2" opacity="0.5"/>` : ''}
    <path d="M12 3L4 10v10a1 1 0 001 1h4v-6h6v6h4a1 1 0 001-1V10z" fill="${color}" stroke="rgba(0,0,0,0.3)" stroke-width="0.5"/>
    <path d="M12 3L4 10h16z" fill="${color}" stroke="rgba(0,0,0,0.3)" stroke-width="0.5"/>
  </svg>`;
}

// Inline SVG for apartment/building icon
function apartmentSvg(color: string, size: number, selected: boolean): string {
  return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" role="img" aria-label="Multi-unit apartment building">
    <title>Multi-unit apartment building</title>
    ${selected ? `<circle cx="12" cy="12" r="12" fill="none" stroke="white" stroke-width="2" opacity="0.5"/>` : ''}
    <rect x="4" y="3" width="16" height="18" rx="1" fill="${color}" stroke="rgba(0,0,0,0.3)" stroke-width="0.5"/>
    <rect x="7" y="6" width="3" height="2.5" rx="0.3" fill="rgba(255,255,255,0.5)"/>
    <rect x="14" y="6" width="3" height="2.5" rx="0.3" fill="rgba(255,255,255,0.5)"/>
    <rect x="7" y="11" width="3" height="2.5" rx="0.3" fill="rgba(255,255,255,0.5)"/>
    <rect x="14" y="11" width="3" height="2.5" rx="0.3" fill="rgba(255,255,255,0.5)"/>
    <rect x="10" y="16" width="4" height="5" rx="0.3" fill="rgba(255,255,255,0.4)"/>
  </svg>`;
}

/** Compact dropdown UI for multi-unit buildings (replaces long scrollable list) */
function MultiUnitPopup({
  group,
  addresses,
  selectedAddressId,
  onAddressClick,
  token,
}: {
  group: AddressGroup;
  addresses: CanvassAddress[];
  selectedAddressId: string | null;
  onAddressClick: (addressId: string) => void;
  token: ReturnType<typeof theme.useToken>['token'];
}) {
  // Default to the selected address in this building, or the first address
  const initialId = addresses.find((a) => a.id === selectedAddressId)?.id ?? addresses[0]?.id ?? '';
  const [viewingId, setViewingId] = useState(initialId);
  const viewingAddr = addresses.find((a) => a.id === viewingId) ?? addresses[0];

  const visitedCount = addresses.filter((a) => a.lastVisit).length;

  return (
    <>
      {/* Header */}
      <div style={{ marginBottom: 8, paddingBottom: 8, borderBottom: `2px solid ${token.colorPrimary}` }}>
        <div style={{ fontWeight: 600, fontSize: 14, color: token.colorPrimary }}>
          🏢 {group.baseAddress}
        </div>
        <div style={{ fontSize: 11, color: '#666', marginTop: 2 }}>
          {addresses.length} units · {visitedCount} visited
        </div>
      </div>

      {/* Building notes */}
      {group.buildingNotes && (
        <Alert
          message="Building Notes"
          description={
            <div dangerouslySetInnerHTML={{ __html: sanitizeHtml(group.buildingNotes) }} />
          }
          type="info"
          showIcon
          style={{ marginBottom: 12, fontSize: 11 }}
        />
      )}

      {/* Native <select> dropdown — Ant Design Select doesn't work inside Leaflet popups */}
      <select
        value={viewingId}
        onChange={(e) => setViewingId(e.target.value)}
        style={{
          width: '100%',
          padding: '8px 10px',
          fontSize: 13,
          borderRadius: 6,
          border: '1px solid #d9d9d9',
          background: '#fafafa',
          marginBottom: 10,
          cursor: 'pointer',
          appearance: 'auto',
        }}
        aria-label="Select unit"
      >
        {addresses.map((addr) => {
          const status = addr.lastVisit
            ? VISIT_OUTCOME_LABELS[addr.lastVisit.outcome]
            : 'Not visited';
          return (
            <option key={addr.id} value={addr.id}>
              Unit {addr.unitNumber || '—'} — {status}
            </option>
          );
        })}
      </select>

      {/* Selected unit detail card */}
      {viewingAddr && (
        <button
          type="button"
          onClick={() => onAddressClick(viewingAddr.id)}
          aria-label={`Record visit for unit ${viewingAddr.unitNumber || 'main'}`}
          style={{
            all: 'unset',
            display: 'block',
            width: '100%',
            boxSizing: 'border-box',
            padding: 10,
            borderRadius: 8,
            border: `1px solid ${viewingAddr.id === selectedAddressId ? token.colorPrimary : '#e8e8e8'}`,
            background: viewingAddr.id === selectedAddressId ? 'rgba(52, 152, 219, 0.06)' : '#fafafa',
            cursor: 'pointer',
          }}
        >
          {viewingAddr.unitNumber && (
            <div style={{ fontSize: 13, fontWeight: 600, color: '#333', marginBottom: 4 }}>
              Unit {viewingAddr.unitNumber}
            </div>
          )}
          {viewingAddr.firstName && (
            <div style={{ fontSize: 12, color: '#555', marginBottom: 4 }}>
              {viewingAddr.firstName} {viewingAddr.lastName}
            </div>
          )}
          <div style={{ fontSize: 12, marginBottom: viewingAddr.notes ? 4 : 0 }}>
            {viewingAddr.lastVisit ? (
              <>
                <span
                  style={{
                    display: 'inline-block',
                    width: 8,
                    height: 8,
                    borderRadius: '50%',
                    backgroundColor: getMarkerColor(viewingAddr),
                    marginRight: 5,
                    verticalAlign: 'middle',
                  }}
                />
                <span style={{ verticalAlign: 'middle' }}>
                  {VISIT_OUTCOME_LABELS[viewingAddr.lastVisit.outcome]}
                </span>
                {viewingAddr.lastVisit.visitorName && (
                  <span style={{ fontSize: 11, color: '#888', marginLeft: 6 }}>
                    by {viewingAddr.lastVisit.visitorName}
                  </span>
                )}
              </>
            ) : (
              <span style={{ color: '#999' }}>Not visited</span>
            )}
          </div>
          {viewingAddr.notes && (
            <div style={{ fontSize: 11, color: '#888', fontStyle: 'italic' }}>
              Note: {viewingAddr.notes}
            </div>
          )}
          <div style={{ fontSize: 11, color: '#1890ff', marginTop: 8, textAlign: 'center' }}>
            Tap to record visit
          </div>
        </button>
      )}
    </>
  );
}

function CanvassMarkerGroup({ group, selectedAddressId, onAddressClick }: CanvassMarkerGroupProps) {
  const addresses = group.addresses;
  const isMultiUnit = group.isMultiUnit;
  const hasAnySelected = addresses.some((addr) => addr.id === selectedAddressId);
  const size = hasAnySelected ? MARKER_SIZE_SELECTED : MARKER_SIZE_DEFAULT;
  const { token } = theme.useToken();

  // For multi-unit, use dominant outcome color; for single-unit, use that address's color
  const color = useMemo(() => {
    if (isMultiUnit) {
      return getDominantOutcomeColor(addresses);
    } else {
      return getMarkerColor(addresses[0]!);
    }
  }, [addresses, isMultiUnit]);

  const icon = useMemo(() => {
    const svgHtml = isMultiUnit
      ? apartmentSvg(color, size, hasAnySelected)
      : houseSvg(color, size, hasAnySelected);

    return L.divIcon({
      html: `<div style="width:${MARKER_TOUCH_TARGET}px;height:${MARKER_TOUCH_TARGET}px;display:flex;align-items:center;justify-content:center">${svgHtml}</div>`,
      iconSize: [MARKER_TOUCH_TARGET, MARKER_TOUCH_TARGET],
      iconAnchor: [MARKER_ANCHOR_OFFSET, MARKER_ANCHOR_OFFSET],
      className: '',
    });
  }, [color, size, hasAnySelected, isMultiUnit]);

  return (
    <Marker
      position={[group.latitude, group.longitude]}
      icon={icon}
      // @ts-expect-error - Pass group data for cluster icon access
      addressGroup={group}
    >
      <Popup maxWidth={350} minWidth={250}>
        <div style={{ minWidth: 230, maxWidth: 330 }}>
          {isMultiUnit ? (
            // Multi-unit building display — compact dropdown
            <MultiUnitPopup
              group={group}
              addresses={addresses}
              selectedAddressId={selectedAddressId}
              onAddressClick={onAddressClick}
              token={token}
            />
          ) : (
            // Single unit display
            <div style={{ cursor: 'pointer' }} onClick={() => onAddressClick(addresses[0]!.id)}>
              <div style={{ fontWeight: 600, fontSize: 13, marginBottom: 4 }}>
                {group.baseAddress}
              </div>
              {addresses[0]?.unitNumber && (
                <div style={{ fontSize: 12, color: '#666', marginBottom: 4 }}>
                  Unit {addresses[0].unitNumber}
                </div>
              )}
              {addresses[0]?.firstName && (
                <div style={{ fontSize: 12, color: '#666', marginBottom: 4 }}>
                  {addresses[0].firstName} {addresses[0].lastName}
                </div>
              )}
              {addresses[0]?.lastVisit ? (
                <>
                  <div style={{ fontSize: 12, marginTop: 4 }}>
                    <span
                      style={{
                        display: 'inline-block',
                        width: 8,
                        height: 8,
                        borderRadius: '50%',
                        backgroundColor: getMarkerColor(addresses[0]),
                        marginRight: 4,
                      }}
                    />
                    {VISIT_OUTCOME_LABELS[addresses[0].lastVisit.outcome]}
                  </div>
                  {addresses[0].lastVisit.visitorName && (
                    <div style={{ fontSize: 11, color: '#888', marginTop: 2 }}>
                      by {addresses[0].lastVisit.visitorName}
                    </div>
                  )}
                </>
              ) : (
                <div style={{ fontSize: 12, color: '#888', marginTop: 4 }}>Not visited</div>
              )}
              {addresses[0]?.notes && (
                <div style={{ fontSize: 11, color: '#888', marginTop: 4, fontStyle: 'italic' }}>
                  Note: {addresses[0].notes}
                </div>
              )}
              <div style={{ fontSize: 11, color: '#1890ff', marginTop: 8, textAlign: 'center' }}>
                Click to record visit
              </div>
            </div>
          )}
        </div>
      </Popup>
    </Marker>
  );
}

// Memoize component to prevent re-renders when props haven't changed
export default React.memo(CanvassMarkerGroup, (prevProps, nextProps) => {
  // Only re-render if these specific props change
  return (
    prevProps.group.locationId === nextProps.group.locationId &&
    prevProps.group.addresses === nextProps.group.addresses &&
    prevProps.selectedAddressId === nextProps.selectedAddressId &&
    prevProps.onAddressClick === nextProps.onAddressClick
  );
});
