import React from 'react';
import Box from '@mui/material/Box';
import Paper from '@mui/material/Paper';
import IconButton from '@mui/material/IconButton';
import ButtonBase from '@mui/material/ButtonBase';
import MapOutlinedIcon from '@mui/icons-material/MapOutlined';
import CloseRoundedIcon from '@mui/icons-material/CloseRounded';
import LocationOnOutlinedIcon from '@mui/icons-material/LocationOnOutlined';
import StarRoundedIcon from '@mui/icons-material/StarRounded';
import VerifiedOutlinedIcon from '@mui/icons-material/VerifiedOutlined';
import type { SxProps, Theme } from '@mui/material/styles';
import { Typography } from '../../atoms/Typography';

// ─── Types ──────────────────────────────────────────────────────────────────

/** A provider summary used in the cluster list */
export interface ClusterPopupProvider {
  /** Unique provider ID */
  id: string;
  /** Provider display name */
  name: string;
  /** Location text (suburb, city) */
  location: string;
  /** Whether this is a verified/partner provider — drives sort order + colour accents */
  verified?: boolean;
  /** Average rating */
  rating?: number;
  /** Starting package price in dollars — shown as "From $X" on the right */
  startingPrice?: number;
  /** Custom price label (e.g. "POA") — overrides the formatted price */
  priceLabel?: string;
}

/** Props for the FA ClusterPopup molecule */
export interface ClusterPopupProps {
  /** Providers in this cluster */
  providers: ClusterPopupProvider[];
  /** Click handler — fires when a provider row is clicked */
  onSelectProvider: (id: string) => void;
  /** Close handler — fires when the close button is clicked */
  onClose?: () => void;
  /** When true, animates the popup out (opacity + scale) without unmounting.
   *  Callers should unmount after the transition completes (180ms). */
  exiting?: boolean;
  /** MUI sx prop for the root element */
  sx?: SxProps<Theme>;
}

// ─── Constants ──────────────────────────────────────────────────────────────

const POPUP_WIDTH = 320;
const MAX_CONTENT_HEIGHT = 360;
const NUB_SIZE = 8;
/** Fixed width reserved for the verified-icon slot so all row titles share
 *  the same x-origin regardless of whether the row is verified. */
const VERIFIED_SLOT_WIDTH = 18;

// ─── Row sub-component ──────────────────────────────────────────────────────

interface ProviderRowProps {
  provider: ClusterPopupProvider;
  onClick: () => void;
}

/**
 * Single provider row inside the cluster list. Image-free layout:
 * verified-icon slot (fixed width so titles align across rows) + name +
 * location/rating meta. Full-width clickable surface. Clicking triggers
 * `onClick` — in `ProviderMap` that pans+zooms the map to the provider's
 * location and opens their single-provider popup.
 */
const ProviderRow: React.FC<ProviderRowProps> = ({ provider, onClick }) => {
  const hasPrice = provider.startingPrice != null || provider.priceLabel != null;
  const priceText =
    provider.priceLabel ??
    (provider.startingPrice != null ? `$${provider.startingPrice.toLocaleString('en-AU')}` : null);

  return (
    <ButtonBase
      onClick={(e) => {
        // stopPropagation so the DOM click doesn't bubble to Map.onClick
        // (which would clear state the same frame we're trying to drill in).
        e.stopPropagation();
        onClick();
      }}
      sx={{
        width: '100%',
        display: 'flex',
        // flex-start so the verified-icon slot aligns with the name's top line,
        // not the vertical centre of the row.
        alignItems: 'flex-start',
        gap: 1,
        p: 1.25,
        borderRadius: 1,
        textAlign: 'left',
        transition: 'background-color 120ms ease-in-out',
        '&:hover': {
          bgcolor: provider.verified
            ? 'var(--fa-color-brand-50)'
            : 'var(--fa-color-surface-subtle)',
        },
        '&:focus-visible': {
          outline: '2px solid var(--fa-color-interactive-focus)',
          outlineOffset: 2,
        },
      }}
    >
      {/* Verified-icon slot — reserved width + fixed line-height so the icon
          sits vertically on the name's line-box regardless of whether the
          row has location/rating/price content below. */}
      <Box
        sx={{
          width: VERIFIED_SLOT_WIDTH,
          flexShrink: 0,
          height: '1.25em',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        {provider.verified && (
          <VerifiedOutlinedIcon
            sx={{ fontSize: 16, color: 'var(--fa-color-brand-600)' }}
            aria-label="Verified provider"
          />
        )}
      </Box>

      {/* Text column — name + location/rating meta */}
      <Box sx={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 0.25 }}>
        <Typography
          variant="body2"
          sx={{
            fontWeight: 600,
            color: provider.verified ? 'var(--fa-color-brand-700)' : 'text.primary',
            minWidth: 0,
            lineHeight: 1.25,
          }}
          maxLines={1}
        >
          {provider.name}
        </Typography>

        <Box
          sx={{
            display: 'flex',
            alignItems: 'center',
            gap: 1,
            color: 'text.secondary',
            flexWrap: 'wrap',
          }}
        >
          <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.25 }}>
            <LocationOnOutlinedIcon sx={{ fontSize: 12 }} aria-hidden />
            <Typography variant="caption" color="text.secondary" sx={{ fontSize: 11 }}>
              {provider.location}
            </Typography>
          </Box>

          {provider.rating != null && (
            <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.25 }}>
              <StarRoundedIcon sx={{ fontSize: 12, color: 'warning.main' }} aria-hidden />
              <Typography variant="caption" color="text.secondary" sx={{ fontSize: 11 }}>
                {provider.rating}
              </Typography>
            </Box>
          )}
        </Box>
      </Box>

      {/* Price column — right-aligned, matches MapPopup's "From $X" typography.
          Verified providers get the brand-600 copper price; unverified get
          text.primary. "From" label uses caption/secondary for hierarchy. */}
      {hasPrice && (
        <Box
          sx={{
            flexShrink: 0,
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'flex-end',
            pt: '1px',
          }}
        >
          <Typography variant="caption" color="text.secondary" sx={{ fontSize: 10 }}>
            From
          </Typography>
          <Typography
            variant="body2"
            sx={{
              fontWeight: 700,
              fontSize: 13,
              color: provider.verified ? 'var(--fa-color-brand-600)' : 'text.primary',
              lineHeight: 1.2,
            }}
          >
            {priceText}
          </Typography>
        </Box>
      )}
    </ButtonBase>
  );
};

// ─── Component ──────────────────────────────────────────────────────────────

/**
 * Cluster popup card for the FA design system.
 *
 * Appears when a cluster marker is clicked. Shows the providers grouped at
 * that map location as a scrollable stack of image-free rows — each row: a
 * fixed-width verified-icon slot (so titles align across mixed-tier lists) +
 * provider name (copper for verified, neutral for unverified) + location and
 * rating meta. Clicking a row calls `onSelectProvider(id)`. In the
 * ProviderMap flow, that pans and zooms the map to the provider's location
 * before opening their single-provider popup — restoring spatial context
 * that a list-only popup otherwise loses.
 *
 * Verified providers are sorted to the top of the list (business outcome:
 * promote partner providers in any crowded cluster).
 *
 * Sibling to `MapPopup` — same card + nub treatment, same drop-shadow, same
 * 320px width, same `surface-subtle` header bar convention. Designed to
 * render inside a Google Maps `AdvancedMarker`.
 *
 * Composes: Paper + Typography + IconButton + ButtonBase + icons.
 *
 * Usage:
 * ```tsx
 * <ClusterPopup
 *   providers={[
 *     { id: 'p1', name: 'H.Parsons', location: 'Wentworth', verified: true, rating: 4.6 },
 *     { id: 'p2', name: 'Smith & Sons', location: 'Cronulla', verified: false, rating: 4.2 },
 *   ]}
 *   onSelectProvider={(id) => drillIntoProvider(id)}
 *   onClose={() => closePopup()}
 * />
 * ```
 */
export const ClusterPopup = React.forwardRef<HTMLDivElement, ClusterPopupProps>(
  ({ providers, onSelectProvider, onClose, exiting = false, sx }, ref) => {
    // Verified-first sort (stable within each tier)
    const sorted = React.useMemo(
      () =>
        [...providers].sort((a, b) => Number(b.verified ?? false) - Number(a.verified ?? false)),
      [providers],
    );

    return (
      <Box
        ref={ref}
        // Swallow clicks on any empty space inside the popup (header, scroll
        // gutter, etc.) so they don't bubble to Map.onClick and close us.
        onClick={(e) => e.stopPropagation()}
        sx={[
          {
            display: 'inline-flex',
            flexDirection: 'column',
            alignItems: 'center',
            filter: 'drop-shadow(0 2px 8px rgba(0,0,0,0.15))',
            transformOrigin: 'bottom center',
            transition: 'opacity 180ms ease-out, transform 180ms ease-out',
            opacity: exiting ? 0 : 1,
            transform: exiting ? 'scale(0.9)' : 'scale(1)',
            '@keyframes clusterPopupIn': {
              from: { opacity: 0, transform: 'scale(0.9)' },
              to: { opacity: 1, transform: 'scale(1)' },
            },
            animation: exiting ? undefined : 'clusterPopupIn 180ms ease-out',
          },
          ...(Array.isArray(sx) ? sx : [sx]),
        ]}
      >
        <Paper
          elevation={0}
          sx={{
            width: POPUP_WIDTH,
            borderRadius: 'var(--fa-card-border-radius-default)',
            overflow: 'hidden',
            bgcolor: 'background.paper',
            display: 'flex',
            flexDirection: 'column',
            maxHeight: MAX_CONTENT_HEIGHT,
          }}
        >
          {/* Header bar */}
          <Box
            sx={{
              display: 'flex',
              alignItems: 'center',
              gap: 1,
              px: 2,
              py: 1.25,
              bgcolor: 'var(--fa-color-surface-subtle)',
              borderBottom: '1px solid',
              borderColor: 'divider',
              flexShrink: 0,
            }}
          >
            <MapOutlinedIcon sx={{ fontSize: 16, color: 'text.secondary' }} aria-hidden />
            <Typography variant="body2" sx={{ fontWeight: 600, color: 'text.primary', flex: 1 }}>
              {providers.length} providers in this area
            </Typography>
            {onClose && (
              <IconButton
                size="small"
                onClick={(e) => {
                  e.stopPropagation();
                  onClose();
                }}
                aria-label="Close cluster popup"
                sx={{ mr: -0.5 }}
              >
                <CloseRoundedIcon sx={{ fontSize: 18 }} />
              </IconButton>
            )}
          </Box>

          {/* Provider list — scrollable */}
          <Box
            sx={{
              overflowY: 'auto',
              p: 1,
              display: 'flex',
              flexDirection: 'column',
              gap: 1,
              // Thin scrollbar styling
              scrollbarWidth: 'thin',
              '&::-webkit-scrollbar': { width: 6 },
              '&::-webkit-scrollbar-thumb': {
                background: 'rgba(0,0,0,0.2)',
                borderRadius: 3,
              },
            }}
          >
            {sorted.map((p) => (
              <ProviderRow key={p.id} provider={p} onClick={() => onSelectProvider(p.id)} />
            ))}
          </Box>
        </Paper>

        {/* Nub — matches MapPopup (fill-only, soft shadow carries the depth) */}
        <svg
          aria-hidden
          width={NUB_SIZE * 2}
          height={NUB_SIZE}
          viewBox={`0 0 ${NUB_SIZE * 2} ${NUB_SIZE}`}
          style={{ display: 'block', marginTop: '-1px', overflow: 'visible' }}
        >
          <path
            d={`M 0 0 L ${NUB_SIZE} ${NUB_SIZE} L ${NUB_SIZE * 2} 0`}
            fill="var(--fa-color-white)"
          />
        </svg>
      </Box>
    );
  },
);

ClusterPopup.displayName = 'ClusterPopup';
export default ClusterPopup;
