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 Timeframe = 'soon' | 'future';
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;
  /** Pre-planning timeframe — only present when status is 'preplanning' */
  timeframe?: Timeframe;
  /** 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;
  /** 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: 'A recent loss or one expected soon',
  },
  {
    key: 'preplanning',
    title: 'Pre-planning',
    description: 'Planning ahead for yourself or a loved one',
  },
];

const TIMEFRAME_OPTIONS: { key: Timeframe; label: string }[] = [
  { key: 'soon', label: 'In the coming weeks or months' },
  { key: 'future', label: 'No set timeframe, I\u2019m planning ahead' },
];

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: 'text.secondary' }}>
      {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 150ms ease-in-out, background-color 150ms ease-in-out, transform 150ms ease-in-out',
      '&: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',
        fontSize: { xs: '0.875rem', sm: '1rem' },
        mb: description ? 0.75 : 0,
        color: selected ? 'var(--fa-color-text-brand, #B0610F)' : 'text.primary',
      }}
    >
      {title}
    </Typography>
    {description && (
      <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: '12px',
  px: 2,
  fontSize: '0.9375rem',
  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, 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 | ''>('immediate');
    const [timeframe, setTimeframe] = React.useState<Timeframe | ''>('');
    const [funeralType, setFuneralType] = React.useState<FuneralType | ''>('');
    const [location, setLocation] = React.useState('');
    const [errors, setErrors] = React.useState<{
      status?: boolean;
      timeframe?: 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]);

    const isPrePlanning = status === 'preplanning';

    // ─── 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();
        const newStatus = STATUS_OPTIONS[next].key;
        setStatus(newStatus);
        if (newStatus !== 'preplanning') setTimeframe('');
      }
    };

    const handleStatusClick = (key: Status) => {
      setStatus(key);
      if (key !== 'preplanning') setTimeframe('');
      if (errors.timeframe) setErrors((prev) => ({ ...prev, timeframe: false }));
    };

    // ─── 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 (status === 'preplanning' && !timeframe) {
        setErrors({ timeframe: 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,
        ...(status === 'preplanning' && timeframe ? { timeframe } : {}),
        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: { xs: 3, sm: 4 },
          },
          ...(Array.isArray(sx) ? sx : [sx]),
        ]}
      >
        {/* ── How can we help ─────────────────────────────────── */}
        <Box ref={statusSectionRef}>
          <SectionLabel id={statusLabelId}>How Can We Help</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={() => handleStatusClick(opt.key)}
                tabIndex={i === activeStatusIndex ? 0 : -1}
                onKeyDown={handleStatusKeyDown}
              />
            ))}
          </Box>
          <Box aria-live="polite" sx={{ textAlign: 'center' }}>
            {errors.status && (
              <Typography
                variant="caption"
                role="alert"
                sx={{
                  color: 'var(--fa-color-text-brand, #B0610F)',
                  display: 'block',
                  mt: 1,
                }}
              >
                Please select how we can help
              </Typography>
            )}
          </Box>

          {/* ── Timeframe follow-up (pre-planning only) ────────── */}
          {isPrePlanning && (
            <Box
              sx={{
                mt: 3,
                overflow: 'hidden',
                animation: 'fadeSlideIn 200ms ease-out',
                '@keyframes fadeSlideIn': {
                  '0%': { opacity: 0, transform: 'translateY(-8px)' },
                  '100%': { opacity: 1, transform: 'translateY(0)' },
                },
              }}
            >
              <SectionLabel id={`${id}-timeframe`}>How Soon Might You Need This?</SectionLabel>
              <Box
                role="radiogroup"
                aria-labelledby={`${id}-timeframe`}
                sx={{
                  display: 'grid',
                  gridTemplateColumns: { xs: '1fr', sm: '1fr 1fr' },
                  gap: 2,
                  mt: 2,
                  '& button': { fontSize: '0.8125rem' },
                  '& button .MuiTypography-root': { fontSize: '0.8125rem' },
                }}
              >
                {TIMEFRAME_OPTIONS.map((opt) => (
                  <StatusCard
                    key={opt.key}
                    title={opt.label}
                    description=""
                    selected={timeframe === opt.key}
                    onClick={() => {
                      setTimeframe(opt.key);
                      if (errors.timeframe) setErrors((prev) => ({ ...prev, timeframe: false }));
                    }}
                  />
                ))}
              </Box>
              <Box aria-live="polite" sx={{ textAlign: 'center' }}>
                {errors.timeframe && (
                  <Typography
                    variant="caption"
                    role="alert"
                    sx={{
                      color: 'var(--fa-color-text-brand, #B0610F)',
                      display: 'block',
                      mt: 1,
                    }}
                  >
                    Please select a timeframe
                  </Typography>
                )}
              </Box>
            </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.25, mr: -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,
                  pl: 0.75,
                  '&::placeholder': {
                    color: 'var(--fa-color-text-disabled)',
                    opacity: 1,
                  },
                },
              }}
              inputProps={{
                'aria-labelledby': locationLabelId,
                'aria-required': true,
              }}
            />
          </Box>
          <Box aria-live="polite">
            {errors.location && (
              <Typography
                variant="caption"
                role="alert"
                sx={{
                  color: 'var(--fa-color-text-brand, #B0610F)',
                  display: 'block',
                  mt: 1,
                }}
              >
                Please enter a suburb or postcode
              </Typography>
            )}
          </Box>
        </Box>

        <Divider />

        {/* ── CTA ─────────────────────────────────────────────── */}
        <Box>
          <Button
            variant="contained"
            size="large"
            fullWidth
            loading={loading}
            endIcon={!loading ? <ArrowForwardIcon /> : undefined}
            onClick={handleSubmit}
            sx={{ minHeight: { xs: 40, sm: 52 }, fontSize: { xs: '0.875rem', sm: undefined } }}
          >
            Search
          </Button>
          <Typography
            variant="caption"
            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;
