import React from 'react';
import Box from '@mui/material/Box';
import Select, { type SelectChangeEvent } from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import OutlinedInput from '@mui/material/OutlinedInput';
import InputAdornment from '@mui/material/InputAdornment';
import LocationOnOutlinedIcon from '@mui/icons-material/LocationOnOutlined';
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
import type { SxProps, Theme } from '@mui/material/styles';
import { Typography } from '../../atoms/Typography';
import { Button } from '../../atoms/Button';
import { Divider } from '../../atoms/Divider';

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

type Status = 'immediate' | 'preplanning';
type FuneralType =
  | 'cremation-funeral'
  | 'cremation-only'
  | 'burial-funeral'
  | 'graveside-only'
  | 'water-cremation'
  | 'show-all';

/** Search parameters returned on form submission */
export interface FuneralFinderV3SearchParams {
  /** User's current situation */
  status: Status;
  /** Type of funeral selected (defaults to show-all if not chosen) */
  funeralType: FuneralType;
  /** Suburb or postcode */
  location: string;
}

/** Props for the FuneralFinder v3 organism */
export interface FuneralFinderV3Props {
  /** Called when the user submits with valid data */
  onSearch?: (params: FuneralFinderV3SearchParams) => void;
  /** Shows loading state on the CTA */
  loading?: boolean;
  /** Optional heading override */
  heading?: string;
  /** Optional subheading override */
  subheading?: string;
  /** MUI sx override for the root container */
  sx?: SxProps<Theme>;
}

// ─── Options ─────────────────────────────────────────────────────────────────

const STATUS_OPTIONS: { key: Status; title: string; description: string }[] = [
  {
    key: 'immediate',
    title: 'Immediate Need',
    description: 'For a recent or expected loss',
  },
  {
    key: 'preplanning',
    title: 'Pre-planning',
    description: 'For yourself or a loved one',
  },
];

const FUNERAL_TYPE_OPTIONS: { value: FuneralType; label: string }[] = [
  { value: 'cremation-funeral', label: 'Cremation with funeral' },
  {
    value: 'cremation-only',
    label: 'Cremation only (no funeral, no attendance)',
  },
  { value: 'burial-funeral', label: 'Burial with funeral' },
  { value: 'graveside-only', label: 'Graveside burial only' },
  { value: 'water-cremation', label: 'Water cremation (QLD only)' },
  { value: 'show-all', label: 'Show all options' },
];

/** Hoisted outside component to avoid re-creation on render */
const selectPlaceholder = (
  <span style={{ color: 'var(--fa-color-text-disabled)' }}>
    Select funeral type
  </span>
);

// ─── Sub-components ──────────────────────────────────────────────────────────

/** Uppercase section label — overline style */
function SectionLabel({
  children,
  id,
}: {
  children: React.ReactNode;
  id?: string;
}) {
  return (
    <Typography
      variant="overline"
      component="div"
      id={id}
      sx={{ color: 'var(--fa-color-brand-800, #6B3C13)' }}
    >
      {children}
    </Typography>
  );
}

/** Tappable status card with roving tabindex support for radiogroup pattern */
const StatusCard = React.forwardRef<
  HTMLButtonElement,
  {
    title: string;
    description: string;
    selected: boolean;
    onClick: () => void;
    tabIndex?: number;
    onKeyDown?: React.KeyboardEventHandler;
  }
>(({ title, description, selected, onClick, tabIndex, onKeyDown }, ref) => (
  <Box
    component="button"
    type="button"
    role="radio"
    aria-checked={selected}
    onClick={onClick}
    ref={ref}
    tabIndex={tabIndex}
    onKeyDown={onKeyDown}
    sx={{
      width: '100%',
      px: 2.5,
      py: 2.5,
      border: '2px solid',
      borderColor: selected
        ? 'var(--fa-color-border-brand, #BA834E)'
        : 'var(--fa-color-border-default, #E8E8E8)',
      borderRadius: 'var(--fa-card-border-radius-default, 8px)',
      bgcolor: selected
        ? 'var(--fa-color-surface-warm, #FEF9F5)'
        : 'var(--fa-color-surface-default, #fff)',
      cursor: 'pointer',
      fontFamily: 'inherit',
      textAlign: 'center',
      transition:
        'border-color 200ms ease, background-color 200ms ease, transform 100ms ease',
      '&:hover': {
        borderColor: selected
          ? 'var(--fa-color-border-brand, #BA834E)'
          : 'var(--fa-color-border-strong, #BFBFBF)',
        bgcolor: selected
          ? 'var(--fa-color-surface-warm, #FEF9F5)'
          : 'var(--fa-color-surface-subtle, #FAFAFA)',
      },
      '&:active': {
        transform: 'scale(0.98)',
      },
      '&:focus-visible': {
        outline: '2px solid var(--fa-color-interactive-focus, #BA834E)',
        outlineOffset: 2,
      },
    }}
  >
    <Typography
      variant="body1"
      component="span"
      sx={{
        fontWeight: 600,
        display: 'block',
        mb: 0.75,
        color: selected
          ? 'var(--fa-color-text-brand, #B0610F)'
          : 'text.primary',
      }}
    >
      {title}
    </Typography>
    <Typography
      variant="caption"
      component="span"
      sx={{
        display: 'block',
        color: 'text.secondary',
        lineHeight: 1.4,
      }}
    >
      {description}
    </Typography>
  </Box>
));
StatusCard.displayName = 'StatusCard';

// ─── Shared field styles ────────────────────────────────────────────────────

/** Standard outlined fields — white bg, neutral border, no focus ring per design spec */
const fieldBaseSx = {
  width: '100%',
  bgcolor: 'var(--fa-color-surface-default, #fff)',
  borderRadius: 'var(--fa-border-radius-md, 8px)',
  '& .MuiOutlinedInput-notchedOutline': {
    borderColor: 'var(--fa-color-border-default, #E8E8E8)',
    borderRadius: 'var(--fa-border-radius-md, 8px)',
  },
  '&:hover:not(.Mui-disabled) .MuiOutlinedInput-notchedOutline': {
    borderColor: 'var(--fa-color-border-strong, #BFBFBF)',
  },
  '&.Mui-focused .MuiOutlinedInput-notchedOutline': {
    borderColor: 'var(--fa-color-border-brand, #BA834E)',
    borderWidth: 1,
  },
  '&.Mui-focused': {
    boxShadow: 'none',
  },
};

const fieldInputStyles = {
  py: '14px',
  px: 2,
  fontSize: '1rem',
  fontFamily: 'var(--fa-font-family-body)',
};

const selectMenuProps = {
  PaperProps: {
    sx: {
      mt: 0.5,
      borderRadius: 'var(--fa-border-radius-md, 8px)',
      boxShadow: 'var(--fa-shadow-md)',
      '& .MuiMenuItem-root': {
        py: 1.5,
        px: 2,
        minHeight: 44,
        fontSize: '0.9375rem',
        fontFamily: 'var(--fa-font-family-body)',
        whiteSpace: 'normal' as const,
        '&:hover': { bgcolor: 'var(--fa-color-surface-subtle)' },
        '&.Mui-selected': {
          bgcolor: 'var(--fa-color-surface-warm)',
          fontWeight: 600,
          '&:hover': { bgcolor: 'var(--fa-color-surface-warm)' },
        },
      },
    },
  },
};

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

/**
 * Hero search widget v3 — clean vertical form with status cards.
 *
 * Two tappable status cards (Immediate Need / Pre-planning), a funeral type
 * dropdown, a location input, and a CTA. Standard card container with
 * overline section labels. CTA is always active —
 * clicking it with missing required fields scrolls to the first gap.
 *
 * Required fields: status + location (min 3 chars).
 * Funeral type defaults to "show all" if not selected.
 */
export const FuneralFinderV3 = React.forwardRef<
  HTMLDivElement,
  FuneralFinderV3Props
>((props, ref) => {
  const {
    onSearch,
    loading = false,
    heading = 'Find funeral directors near you',
    subheading =
      "Tell us what you need and we\u2019ll show options in your area.",
    sx,
  } = props;

  // ─── IDs for aria-labelledby ──────────────────────────────
  const id = React.useId();
  const statusLabelId = `${id}-status`;
  const funeralTypeLabelId = `${id}-funeral-type`;
  const locationLabelId = `${id}-location`;

  // ─── State ───────────────────────────────────────────────
  const [status, setStatus] = React.useState<Status | ''>('');
  const [funeralType, setFuneralType] = React.useState<FuneralType | ''>('');
  const [location, setLocation] = React.useState('');
  const [errors, setErrors] = React.useState<{
    status?: boolean;
    location?: boolean;
  }>({});

  // ─── Refs ────────────────────────────────────────────────
  const statusSectionRef = React.useRef<HTMLDivElement>(null);
  const locationSectionRef = React.useRef<HTMLDivElement>(null);
  const locationInputRef = React.useRef<HTMLInputElement>(null);
  const cardRefs = React.useRef<(HTMLButtonElement | null)[]>([null, null]);

  // ─── Clear errors as fields are filled ───────────────────
  const prevStatus = React.useRef(status);
  React.useEffect(() => {
    if (status !== prevStatus.current) {
      prevStatus.current = status;
      if (status && errors.status) {
        setErrors((prev) => ({ ...prev, status: false }));
      }
    }
  }, [status, errors.status]);

  const prevLocation = React.useRef(location);
  React.useEffect(() => {
    if (location !== prevLocation.current) {
      prevLocation.current = location;
      if (location.trim().length >= 3 && errors.location) {
        setErrors((prev) => ({ ...prev, location: false }));
      }
    }
  }, [location, errors.location]);

  // ─── Radiogroup keyboard nav (WAI-ARIA pattern) ──────────
  const activeStatusIndex = status
    ? STATUS_OPTIONS.findIndex((o) => o.key === status)
    : 0;

  const handleStatusKeyDown = (e: React.KeyboardEvent) => {
    const isNext = e.key === 'ArrowRight' || e.key === 'ArrowDown';
    const isPrev = e.key === 'ArrowLeft' || e.key === 'ArrowUp';
    if (!isNext && !isPrev) return;
    e.preventDefault();
    const current = cardRefs.current.indexOf(
      e.target as HTMLButtonElement,
    );
    if (current === -1) return;
    const next = isNext
      ? Math.min(current + 1, STATUS_OPTIONS.length - 1)
      : Math.max(current - 1, 0);
    if (next !== current) {
      cardRefs.current[next]?.focus();
      setStatus(STATUS_OPTIONS[next].key);
    }
  };

  // ─── Handlers ────────────────────────────────────────────
  const handleFuneralType = (e: SelectChangeEvent<string>) => {
    setFuneralType(e.target.value as FuneralType);
  };

  const handleSubmit = () => {
    if (!status) {
      setErrors({ status: true });
      statusSectionRef.current?.scrollIntoView({
        behavior: 'smooth',
        block: 'center',
      });
      return;
    }
    if (location.trim().length < 3) {
      setErrors({ location: true });
      locationSectionRef.current?.scrollIntoView({
        behavior: 'smooth',
        block: 'center',
      });
      locationInputRef.current?.focus();
      return;
    }
    setErrors({});
    onSearch?.({
      status,
      funeralType: funeralType || 'show-all',
      location: location.trim(),
    });
  };

  // ─── Render ──────────────────────────────────────────────
  return (
    <Box
      ref={ref}
      role="search"
      aria-label="Find funeral directors"
      sx={[
        {
          bgcolor: 'var(--fa-color-surface-raised, #fff)',
          borderRadius: 'var(--fa-card-border-radius-default, 8px)',
          boxShadow: 'var(--fa-card-shadow-default)',
          px: { xs: 3.5, sm: 5 },
          py: { xs: 4, sm: 5 },
          display: 'flex',
          flexDirection: 'column',
          gap: 4,
        },
        ...(Array.isArray(sx) ? sx : [sx]),
      ]}
    >
      {/* ── Header ──────────────────────────────────────────── */}
      <Box sx={{ textAlign: 'center' }}>
        <Typography
          variant="h3"
          component="h2"
          sx={{
            fontFamily: 'var(--fa-font-family-display)',
            fontWeight: 400,
            mb: 1,
          }}
        >
          {heading}
        </Typography>
        <Typography variant="body2" color="text.secondary">
          {subheading}
        </Typography>
      </Box>

      <Divider />

      {/* ── Current Status ──────────────────────────────────── */}
      <Box ref={statusSectionRef}>
        <SectionLabel id={statusLabelId}>Current Status</SectionLabel>
        <Box
          role="radiogroup"
          aria-labelledby={statusLabelId}
          sx={{
            display: 'grid',
            gridTemplateColumns: { xs: '1fr', sm: '1fr 1fr' },
            gap: 2,
            mt: 2,
          }}
        >
          {STATUS_OPTIONS.map((opt, i) => (
            <StatusCard
              key={opt.key}
              ref={(el) => {
                cardRefs.current[i] = el;
              }}
              title={opt.title}
              description={opt.description}
              selected={status === opt.key}
              onClick={() => setStatus(opt.key)}
              tabIndex={i === activeStatusIndex ? 0 : -1}
              onKeyDown={handleStatusKeyDown}
            />
          ))}
        </Box>
        <Box
          sx={{ minHeight: '1.5rem', mt: 1, textAlign: 'center' }}
          aria-live="polite"
        >
          {errors.status && (
            <Typography
              variant="caption"
              role="alert"
              sx={{ color: 'var(--fa-color-text-brand, #B0610F)' }}
            >
              Please select your current situation
            </Typography>
          )}
        </Box>
      </Box>

      {/* ── Funeral Type ────────────────────────────────────── */}
      <Box>
        <SectionLabel id={funeralTypeLabelId}>Funeral Type</SectionLabel>
        <Box sx={{ mt: 2 }}>
          <Select
            value={funeralType}
            onChange={handleFuneralType}
            displayEmpty
            renderValue={(v) =>
              v
                ? FUNERAL_TYPE_OPTIONS.find((o) => o.value === v)?.label
                : selectPlaceholder
            }
            MenuProps={selectMenuProps}
            sx={{
              ...fieldBaseSx,
              '& .MuiSelect-select': {
                ...fieldInputStyles,
                minHeight: 'unset !important',
              },
              '& .MuiSelect-icon': {
                color: 'var(--fa-color-text-disabled)',
                right: 12,
              },
            }}
            inputProps={{ 'aria-labelledby': funeralTypeLabelId }}
          >
            {FUNERAL_TYPE_OPTIONS.map((o) => (
              <MenuItem key={o.value} value={o.value}>
                {o.label}
              </MenuItem>
            ))}
          </Select>
        </Box>
      </Box>

      {/* ── Location ────────────────────────────────────────── */}
      <Box ref={locationSectionRef}>
        <SectionLabel id={locationLabelId}>Location</SectionLabel>
        <Box sx={{ mt: 2 }}>
          <OutlinedInput
            value={location}
            onChange={(e) => setLocation(e.target.value)}
            placeholder="Enter suburb or postcode"
            inputRef={locationInputRef}
            startAdornment={
              <InputAdornment position="start" sx={{ ml: 0.5 }}>
                <LocationOnOutlinedIcon
                  sx={{
                    fontSize: 20,
                    color: 'var(--fa-color-text-disabled)',
                  }}
                />
              </InputAdornment>
            }
            onKeyDown={(e) => {
              if (e.key === 'Enter') handleSubmit();
            }}
            sx={{
              ...fieldBaseSx,
              '& .MuiOutlinedInput-input': {
                ...fieldInputStyles,
                '&::placeholder': {
                  color: 'var(--fa-color-text-disabled)',
                  opacity: 1,
                },
              },
            }}
            inputProps={{
              'aria-labelledby': locationLabelId,
              'aria-required': true,
            }}
          />
        </Box>
        <Box
          sx={{ minHeight: '1.5rem', mt: 1 }}
          aria-live="polite"
        >
          {errors.location && (
            <Typography
              variant="caption"
              role="alert"
              sx={{ color: 'var(--fa-color-text-brand, #B0610F)' }}
            >
              Please enter a suburb or postcode
            </Typography>
          )}
        </Box>
      </Box>

      {/* ── CTA ─────────────────────────────────────────────── */}
      <Box>
        <Button
          variant="contained"
          size="large"
          fullWidth
          loading={loading}
          endIcon={!loading ? <ArrowForwardIcon /> : undefined}
          onClick={handleSubmit}
          sx={{ minHeight: 52 }}
        >
          Find Funeral Directors
        </Button>
        <Typography
          variant="captionSm"
          color="text.secondary"
          sx={{ textAlign: 'center', display: 'block', mt: 1.5 }}
        >
          Free to use &middot; No obligation
        </Typography>
      </Box>
    </Box>
  );
});

FuneralFinderV3.displayName = 'FuneralFinderV3';
export default FuneralFinderV3;
