import React from 'react';
import Box from '@mui/material/Box';
import type { SxProps, Theme } from '@mui/material/styles';

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

/** Props for the FA MapPin atom */
export interface MapPinProps {
  /** Provider or venue name — omit for a price-only pill */
  name?: string;
  /** Starting package price in dollars — shown as "From $X" */
  price?: number;
  /** Custom price label (e.g. "POA") — overrides formatted price */
  priceLabel?: string;
  /** Whether this provider/venue is verified (brand colour vs neutral) */
  verified?: boolean;
  /** Whether this pin is currently active/selected */
  active?: boolean;
  /** Click handler */
  onClick?: (e: React.MouseEvent) => void;
  /** MUI sx prop for the root element */
  sx?: SxProps<Theme>;
}

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

const PIN_PX = 'var(--fa-map-pin-padding-x)';
const PIN_RADIUS = 'var(--fa-map-pin-border-radius)';
const NUB_SIZE = 'var(--fa-map-pin-nub-size)';
const MAX_WIDTH = 180;

// ─── Colour sets ────────────────────────────────────────────────────────────

const colours = {
  verified: {
    bg: 'var(--fa-color-brand-100)',
    name: 'var(--fa-color-brand-900)',
    price: 'var(--fa-color-brand-600)',
    activeBg: 'var(--fa-color-brand-700)',
    activeName: 'var(--fa-color-white)',
    activePrice: 'var(--fa-color-brand-200)',
    nub: 'var(--fa-color-brand-100)',
    activeNub: 'var(--fa-color-brand-700)',
    border: 'var(--fa-color-brand-300)',
    activeBorder: 'var(--fa-color-brand-700)',
  },
  unverified: {
    bg: 'var(--fa-color-neutral-100)',
    name: 'var(--fa-color-neutral-800)',
    price: 'var(--fa-color-neutral-500)',
    activeBg: 'var(--fa-color-neutral-700)',
    activeName: 'var(--fa-color-white)',
    activePrice: 'var(--fa-color-neutral-200)',
    nub: 'var(--fa-color-neutral-100)',
    activeNub: 'var(--fa-color-neutral-700)',
    border: 'var(--fa-color-neutral-300)',
    activeBorder: 'var(--fa-color-neutral-700)',
  },
} as const;

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

/**
 * Map marker pin for the FA design system.
 *
 * Two-line label marker showing provider name and starting package
 * price. Renders as a rounded pill with a downward nub pointing to
 * the exact map location.
 *
 * - **Line 1**: Provider name (bold, truncated)
 * - **Line 2**: "From $X" (smaller, secondary colour) — optional
 *
 * Visual distinction:
 * - **Verified** providers: warm brand palette (gold bg, copper text)
 * - **Unverified** providers: neutral grey palette
 * - **Active/selected**: inverted colours (dark bg, white text) + scale-up
 *
 * Designed for use as custom HTML markers in Mapbox GL / Google Maps.
 * Pure CSS — no canvas, no SVG dependency.
 *
 * Usage:
 * ```tsx
 * <MapPin name="H.Parsons" price={900} verified onClick={...} />
 * <MapPin name="Smith & Sons" /> {/* Name only, unverified *\/}
 * <MapPin price={900} verified /> {/* Price-only pill, no name *\/}
 * <MapPin name="H.Parsons" price={900} verified active />
 * ```
 */
export const MapPin = React.forwardRef<HTMLDivElement, MapPinProps>(
  ({ name, price, priceLabel, verified = false, active = false, onClick, sx }, ref) => {
    const palette = verified ? colours.verified : colours.unverified;
    const hasPrice = price != null || priceLabel != null;

    const priceText =
      priceLabel ?? (price != null ? `From $${price.toLocaleString('en-AU')}` : undefined);

    const handleKeyDown = (e: React.KeyboardEvent) => {
      if ((e.key === 'Enter' || e.key === ' ') && onClick) {
        e.preventDefault();
        onClick(e as unknown as React.MouseEvent);
      }
    };

    return (
      <Box
        ref={ref}
        role="button"
        tabIndex={0}
        aria-label={`${name ?? (verified ? 'Verified' : 'Unverified') + ' provider'}${hasPrice ? `, packages from $${price?.toLocaleString('en-AU') ?? priceLabel}` : ''}${verified ? ', verified' : ''}${active ? ' (selected)' : ''}`}
        onClick={onClick}
        onKeyDown={handleKeyDown}
        sx={[
          {
            display: 'inline-flex',
            flexDirection: 'column',
            alignItems: 'center',
            cursor: 'pointer',
            transition: 'transform 150ms ease-in-out',
            transform: active ? 'scale(1.08)' : 'scale(1)',
            '&:hover': {
              transform: 'scale(1.08)',
            },
            '&:focus-visible': {
              outline: 'none',
              '& > .MapPin-label': {
                outline: '2px solid var(--fa-color-interactive-focus)',
                outlineOffset: '2px',
              },
            },
          },
          ...(Array.isArray(sx) ? sx : [sx]),
        ]}
      >
        {/* Label pill */}
        <Box
          className="MapPin-label"
          sx={{
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
            maxWidth: MAX_WIDTH,
            py: 0.5,
            px: PIN_PX,
            borderRadius: PIN_RADIUS,
            backgroundColor: active ? palette.activeBg : palette.bg,
            border: '1px solid',
            borderColor: active ? palette.activeBorder : palette.border,
            boxShadow: active ? 'var(--fa-shadow-md)' : 'var(--fa-shadow-sm)',
            transition:
              'background-color 150ms ease-in-out, border-color 150ms ease-in-out, box-shadow 150ms ease-in-out',
          }}
        >
          {/* Name */}
          {name && (
            <Box
              component="span"
              sx={{
                fontSize: 12,
                fontWeight: 700,
                fontFamily: (t: Theme) => t.typography.fontFamily,
                lineHeight: 1.3,
                color: active ? palette.activeName : palette.name,
                whiteSpace: 'nowrap',
                overflow: 'hidden',
                textOverflow: 'ellipsis',
                maxWidth: '100%',
                transition: 'color 150ms ease-in-out',
              }}
            >
              {name}
            </Box>
          )}

          {/* Price line */}
          {hasPrice && (
            <Box
              component="span"
              sx={{
                fontSize: !name ? 12 : 11,
                fontWeight: !name ? 700 : 600,
                fontFamily: (t: Theme) => t.typography.fontFamily,
                lineHeight: 1.2,
                color: !name
                  ? active
                    ? palette.activeName
                    : palette.name
                  : active
                    ? palette.activePrice
                    : palette.price,
                whiteSpace: 'nowrap',
                transition: 'color 150ms ease-in-out',
              }}
            >
              {priceText}
            </Box>
          )}
        </Box>

        {/* Nub — downward pointer */}
        <Box
          aria-hidden
          sx={{
            width: 0,
            height: 0,
            borderLeft: `${NUB_SIZE} solid transparent`,
            borderRight: `${NUB_SIZE} solid transparent`,
            borderTop: `${NUB_SIZE} solid`,
            borderTopColor: active ? palette.activeNub : palette.nub,
            mt: '-1px',
          }}
        />
      </Box>
    );
  },
);

MapPin.displayName = 'MapPin';
export default MapPin;
