import React from 'react';
import Box from '@mui/material/Box';
import Paper from '@mui/material/Paper';
import Tooltip from '@mui/material/Tooltip';
import LocationOnOutlinedIcon from '@mui/icons-material/LocationOnOutlined';
import StarRoundedIcon from '@mui/icons-material/StarRounded';
import PeopleOutlinedIcon from '@mui/icons-material/PeopleOutlined';
import VerifiedOutlinedIcon from '@mui/icons-material/VerifiedOutlined';
import type { SxProps, Theme } from '@mui/material/styles';
import { Typography } from '../../atoms/Typography';

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

/** Props for the FA MapPopup molecule */
export interface MapPopupProps {
  /** Provider/venue name */
  name: string;
  /** Hero image URL */
  imageUrl?: string;
  /** Price in dollars — shown as "From $X" */
  price?: number;
  /** Custom price label (e.g. "POA") — overrides formatted price */
  priceLabel?: string;
  /** Location text (suburb, city) */
  location?: string;
  /** Average rating (e.g. 4.8) */
  rating?: number;
  /** Venue capacity */
  capacity?: number;
  /** Whether this provider is verified — shows icon badge in image */
  verified?: boolean;
  /** Click handler — entire card is clickable */
  onClick?: () => 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 = 260;
const IMAGE_HEIGHT = 100;
const NUB_SIZE = 8;

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

/**
 * Map popup card for the FA design system.
 *
 * Floating card anchored to a MapPin on click. Shows a compact
 * preview of a provider or venue — image, name, meta, and price.
 * The entire card is clickable to navigate to the provider/venue.
 *
 * Content hierarchy matches MiniCard: **title → meta → price**.
 * Truncated names show a tooltip on hover. Verified providers
 * show an icon-only badge floating in the image.
 *
 * Designed for use as a custom popup in Mapbox GL / Google Maps.
 * The parent map container handles positioning; this component
 * handles content and styling only.
 *
 * Composes: Paper + Typography + Tooltip.
 *
 * Usage:
 * ```tsx
 * <MapPopup
 *   name="H.Parsons Funeral Directors"
 *   imageUrl="/images/parsons.jpg"
 *   price={900}
 *   location="Wollongong"
 *   rating={4.8}
 *   verified
 *   onClick={() => selectProvider(id)}
 * />
 * ```
 */
export const MapPopup = React.forwardRef<HTMLDivElement, MapPopupProps>(
  (
    {
      name,
      imageUrl,
      price,
      priceLabel,
      location,
      rating,
      capacity,
      verified = false,
      onClick,
      exiting = false,
      sx,
    },
    ref,
  ) => {
    const hasMeta = location != null || rating != null || capacity != null;
    const hasPrice = price != null || priceLabel != null;

    // Detect name truncation for tooltip
    const nameRef = React.useRef<HTMLElement>(null);
    const [isTruncated, setIsTruncated] = React.useState(false);

    React.useEffect(() => {
      const el = nameRef.current;
      if (el) {
        setIsTruncated(el.scrollHeight > el.clientHeight + 1);
      }
    }, [name]);

    // Swallow clicks on the popup so they don't bubble to an enclosing
    // Map.onClick (which would close the popup mid-click). Always applied,
    // even when onClick is unset, because callers consistently render this
    // molecule inside a map context where ambient clicks should not escape.
    const handleClick = (e: React.MouseEvent) => {
      e.stopPropagation();
      onClick?.();
    };

    return (
      <Box
        ref={ref}
        role={onClick ? 'button' : undefined}
        tabIndex={onClick ? 0 : undefined}
        onClick={handleClick}
        onKeyDown={
          onClick
            ? (e: React.KeyboardEvent) => {
                if (e.key === 'Enter' || e.key === ' ') {
                  e.preventDefault();
                  onClick();
                }
              }
            : undefined
        }
        aria-label={onClick ? `View ${name}` : undefined}
        sx={[
          {
            display: 'inline-flex',
            flexDirection: 'column',
            alignItems: 'center',
            filter: 'drop-shadow(0 2px 8px rgba(0,0,0,0.15))',
            cursor: onClick ? 'pointer' : 'default',
            transformOrigin: 'bottom center',
            transition: 'opacity 180ms ease-out, transform 180ms ease-out',
            opacity: exiting ? 0 : 1,
            transform: exiting ? 'scale(0.9)' : 'scale(1)',
            '@keyframes mapPopupIn': {
              from: { opacity: 0, transform: 'scale(0.9)' },
              to: { opacity: 1, transform: 'scale(1)' },
            },
            animation: exiting ? undefined : 'mapPopupIn 180ms ease-out',
            '&:hover':
              onClick && !exiting
                ? {
                    transform: 'scale(1.02)',
                  }
                : undefined,
            '&:focus-visible': {
              outline: '2px solid var(--fa-color-interactive-focus)',
              outlineOffset: '2px',
              borderRadius: 'var(--fa-card-border-radius-default)',
            },
          },
          ...(Array.isArray(sx) ? sx : [sx]),
        ]}
      >
        <Paper
          elevation={0}
          sx={{
            width: POPUP_WIDTH,
            borderRadius: 'var(--fa-card-border-radius-default)',
            overflow: 'hidden',
            bgcolor: 'background.paper',
            position: 'relative',
          }}
        >
          {/* ── Image ── */}
          {imageUrl && (
            <Box
              role="img"
              aria-label={`Photo of ${name}`}
              sx={{
                position: 'relative',
                height: IMAGE_HEIGHT,
                backgroundImage: `url(${imageUrl})`,
                backgroundSize: 'cover',
                backgroundPosition: 'center',
                backgroundColor: 'var(--fa-color-neutral-100)',
              }}
            >
              {/* Verified icon badge — floating top-right */}
              {verified && (
                <Tooltip title="Verified provider" arrow placement="top">
                  <Box
                    sx={{
                      position: 'absolute',
                      top: 8,
                      right: 8,
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                      width: 24,
                      height: 24,
                      borderRadius: '50%',
                      backgroundColor: 'var(--fa-color-brand-600)',
                      color: 'var(--fa-color-white)',
                      boxShadow: 'var(--fa-shadow-sm)',
                    }}
                  >
                    <VerifiedOutlinedIcon sx={{ fontSize: 14 }} />
                  </Box>
                </Tooltip>
              )}
            </Box>
          )}

          {/* ── Content ── */}
          <Box sx={{ p: 1.5, display: 'flex', flexDirection: 'column', gap: '4px' }}>
            {/* 1. Name — with tooltip when truncated */}
            <Tooltip
              title={isTruncated ? name : ''}
              arrow
              placement="top"
              enterDelay={300}
              disableHoverListener={!isTruncated}
            >
              <Typography ref={nameRef} variant="body2" sx={{ fontWeight: 600 }} maxLines={1}>
                {name}
              </Typography>
            </Tooltip>

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

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

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

            {/* 3. Price */}
            {hasPrice && (
              <Box sx={{ display: 'flex', alignItems: 'baseline', gap: 0.5 }}>
                {priceLabel ? (
                  <Typography variant="caption" color="primary" sx={{ fontStyle: 'italic' }}>
                    {priceLabel}
                  </Typography>
                ) : (
                  <>
                    <Typography variant="caption" color="text.secondary">
                      From
                    </Typography>
                    <Typography variant="caption" color="primary" sx={{ fontWeight: 600 }}>
                      ${price!.toLocaleString('en-AU')}
                    </Typography>
                  </>
                )}
              </Box>
            )}

            {/* Verified indicator (no-image fallback) */}
            {verified && !imageUrl && (
              <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
                <VerifiedOutlinedIcon sx={{ fontSize: 14, color: 'var(--fa-color-brand-600)' }} />
                <Typography variant="caption" color="text.secondary" sx={{ fontSize: 11 }}>
                  Verified
                </Typography>
              </Box>
            )}
          </Box>
        </Paper>

        {/* Nub — downward pointer. SVG (fill-only; MapPopup uses a drop-shadow
            for depth instead of a hard border, so no stroke needed) */}
        <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>
    );
  },
);

MapPopup.displayName = 'MapPopup';
export default MapPopup;
