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 CheckIcon from '@mui/icons-material/Check';
import type { SxProps, Theme } from '@mui/material/styles';
import { Typography } from '../../atoms/Typography';
import { Button } from '../../atoms/Button';
import { Input } from '../../atoms/Input';
import { Divider } from '../../atoms/Divider';

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

type LookingTo = 'arrange-now' | 'expected' | 'future';
type PlanningFor = 'myself' | 'someone-else';
type FuneralType =
  | 'cremation-funeral'
  | 'cremation-only'
  | 'burial-funeral'
  | 'graveside-only'
  | 'water-cremation';

/** Search parameters returned on form submission */
export interface FuneralFinderV2SearchParams {
  /** User's situation — immediate, expected, or future need */
  lookingTo: LookingTo;
  /** Who the funeral is for */
  planningFor: PlanningFor;
  /** Type of funeral selected */
  funeralType: FuneralType;
  /** Suburb or postcode */
  location: string;
}

/** Props for the FuneralFinder v2 quick-form organism */
export interface FuneralFinderV2Props {
  /** Called when the user submits with valid data */
  onSearch?: (params: FuneralFinderV2SearchParams) => 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 LOOKING_TO_OPTIONS: { value: LookingTo; label: string }[] = [
  { value: 'arrange-now', label: 'Arrange a funeral for someone who has passed' },
  { value: 'expected', label: 'Plan ahead for someone who is unwell' },
  { value: 'future', label: "Plan for a future need that isn't expected soon" },
];

const PLANNING_FOR_OPTIONS: { value: PlanningFor; label: string }[] = [
  { value: 'someone-else', label: 'Someone else' },
  { value: 'myself', label: 'Myself' },
];

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)' },
];

// ─── Layout constants ────────────────────────────────────────────────────────

const STEP_CIRCLE_SIZE = 48;

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

/** Step number circle — transitions to a check icon when the step is completed */
function StepCircle({
  step,
  completed,
  active = false,
  showConnector = false,
}: {
  step: number;
  completed: boolean;
  /** Use primary brand fill even when not completed (for the first/always-active step) */
  active?: boolean;
  /** Show a vertical connector line below this circle to the next step */
  showConnector?: boolean;
}) {
  const usePrimary = completed || active;
  return (
    <Box
      sx={{
        width: STEP_CIRCLE_SIZE,
        height: STEP_CIRCLE_SIZE,
        borderRadius: '50%',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        flexShrink: 0,
        position: 'relative',
        zIndex: 1,
        transition: 'background-color 200ms ease, color 200ms ease',
        ...(usePrimary
          ? { bgcolor: 'var(--fa-color-brand-500)', color: 'common.white' }
          : {
              bgcolor: 'var(--fa-color-brand-200, #EBDAC8)',
              color: 'var(--fa-color-brand-700, #8B4E0D)',
            }),
        // Connector line from bottom of this circle toward the next
        ...(showConnector && {
          '&::after': {
            content: '""',
            position: 'absolute',
            top: '100%',
            left: '50%',
            transform: 'translateX(-50%)',
            width: 3,
            height: 60,
            backgroundColor: 'var(--fa-color-neutral-200)',
            zIndex: -1,
          },
        }),
      }}
    >
      {completed ? (
        <CheckIcon sx={{ fontSize: 24 }} />
      ) : (
        <Typography
          variant="captionSm"
          component="span"
          sx={{ fontWeight: 700, fontSize: '1.375rem', lineHeight: 1, color: 'inherit' }}
        >
          {step}
        </Typography>
      )}
    </Box>
  );
}

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

const selectSx: SxProps<Theme> = {
  width: '100%',
  bgcolor: 'var(--fa-color-surface-default, #fff)',
  '.MuiOutlinedInput-notchedOutline': {
    borderColor: 'var(--fa-color-neutral-200)',
    borderRadius: 'var(--fa-border-radius-md, 8px)',
  },
  '&:hover:not(.Mui-disabled) .MuiOutlinedInput-notchedOutline': {
    borderColor: 'var(--fa-color-brand-400)',
  },
  '&.Mui-focused': {
    boxShadow: 'none',
  },
  '&.Mui-focused .MuiOutlinedInput-notchedOutline': {
    borderColor: 'var(--fa-color-brand-400)',
    borderWidth: 1,
  },
  '&.Mui-disabled': {
    opacity: 0.6,
    '.MuiOutlinedInput-notchedOutline': {
      borderStyle: 'dashed',
    },
  },
  '&.Mui-error .MuiOutlinedInput-notchedOutline': {
    borderColor: 'var(--fa-color-feedback-error-500, #d32f2f)',
  },
  '.MuiSelect-select': {
    py: '14px',
    px: 2,
    fontSize: '0.875rem',
    minHeight: 'unset !important',
  },
  '.MuiSelect-icon': {
    color: 'var(--fa-color-neutral-400)',
  },
};

const selectMenuProps = {
  PaperProps: {
    sx: {
      mt: 0.5,
      borderRadius: 'var(--fa-border-radius-md, 8px)',
      boxShadow: 'var(--fa-shadow-md)',
      minWidth: 280,
      '& .MuiMenuItem-root': {
        py: 1.5,
        px: 2,
        fontSize: '0.875rem',
        whiteSpace: 'normal',
        '&:hover': { bgcolor: 'var(--fa-color-brand-50)' },
        '&.Mui-selected': {
          bgcolor: 'var(--fa-color-surface-warm)',
          fontWeight: 600,
          '&:hover': { bgcolor: 'var(--fa-color-surface-warm)' },
        },
      },
    },
  },
};

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

/**
 * Quick-form funeral search widget for the homepage hero.
 *
 * Three dropdown selects (intent, planning-for, type), a location input,
 * and a CTA — all always visible at a fixed height. Step numbers transition
 * to check icons as the user completes each field.
 *
 * Conditional logic:
 * - "Arrange a funeral for someone who has passed" auto-sets step 2
 *   to "Someone else" and disables it.
 * - "Myself" is only available for pre-planning paths (expected / future).
 */
export const FuneralFinderV2 = React.forwardRef<HTMLDivElement, FuneralFinderV2Props>(
  (
    {
      onSearch,
      loading = false,
      heading = 'Find funeral directors near you',
      subheading = "Tell us what you need and we'll show options in your area.",
      sx,
    },
    ref,
  ) => {
    // ─── State ───────────────────────────────────────────────────
    const [lookingTo, setLookingTo] = React.useState<LookingTo | ''>('');
    const [planningFor, setPlanningFor] = React.useState<PlanningFor | ''>('');
    const [funeralType, setFuneralType] = React.useState<FuneralType | ''>('');
    const [location, setLocation] = React.useState('');
    const [submitted, setSubmitted] = React.useState(false);

    // ─── Derived ─────────────────────────────────────────────────
    const isArrangeNow = lookingTo === 'arrange-now';
    const step2Disabled = !lookingTo || isArrangeNow;
    const step3Disabled = !planningFor;
    const step4Disabled = !funeralType;

    // Errors only show after first submit attempt, then clear as fields fill
    const errs = submitted
      ? {
          lookingTo: !lookingTo,
          planningFor: !planningFor,
          funeralType: !funeralType,
          location: location.trim().length < 3,
        }
      : { lookingTo: false, planningFor: false, funeralType: false, location: false };

    const hasErrors =
      submitted && (errs.lookingTo || errs.planningFor || errs.funeralType || errs.location);

    // ─── Handlers ────────────────────────────────────────────────
    const handleLookingTo = (e: SelectChangeEvent<string>) => {
      const val = e.target.value as LookingTo;
      setLookingTo(val);
      if (val === 'arrange-now') {
        setPlanningFor('someone-else');
      } else {
        setPlanningFor('');
      }
    };

    const handlePlanningFor = (e: SelectChangeEvent<string>) => {
      setPlanningFor(e.target.value as PlanningFor);
    };

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

    const handleSubmit = () => {
      setSubmitted(true);
      if (!lookingTo || !planningFor || !funeralType || location.trim().length < 3) return;
      onSearch?.({
        lookingTo,
        planningFor,
        funeralType,
        location: location.trim(),
      });
    };

    // ─── Helpers ─────────────────────────────────────────────────
    const placeholder = (
      <span style={{ color: 'var(--fa-color-neutral-400)' }}>Select&hellip;</span>
    );

    const findLabel = (opts: { value: string; label: string }[], val: string) =>
      opts.find((o) => o.value === val)?.label ?? '';

    // ─── Render ──────────────────────────────────────────────────
    return (
      <Box
        ref={ref}
        role="search"
        aria-label="Find funeral providers"
        sx={[
          {
            bgcolor: 'background.paper',
            borderRadius: 'var(--fa-card-border-radius-default, 12px)',
            boxShadow: 'var(--fa-shadow-md)',
            px: { xs: 3, sm: 4 },
            pb: { xs: 3, sm: 4 },
            pt: { xs: 4, sm: 5 },
          },
          ...(Array.isArray(sx) ? sx : [sx]),
        ]}
      >
        {/* ── Header ──────────────────────────────────────────── */}
        <Typography
          variant="h3"
          component="h2"
          sx={{ fontFamily: 'var(--fa-font-family-display)', textAlign: 'center', mb: 1 }}
        >
          {heading}
        </Typography>
        <Typography variant="body2" color="text.secondary" sx={{ textAlign: 'center', mb: 0 }}>
          {subheading}
        </Typography>
        <Divider sx={{ my: 3.5 }} />

        {/* ── Steps ───────────────────────────────────────────── */}
        <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
          {/* Step 1: I'm looking to */}
          <Box sx={{ display: 'flex', gap: 2.5, alignItems: 'flex-end' }}>
            <StepCircle step={1} completed={!!lookingTo} active showConnector />
            <Box sx={{ flex: 1 }}>
              <Typography
                variant="body1"
                sx={{ fontWeight: 600, mb: 1, color: 'var(--fa-color-brand-700)' }}
              >
                I&rsquo;m looking to&hellip;
              </Typography>
              <Select
                value={lookingTo}
                onChange={handleLookingTo}
                displayEmpty
                error={errs.lookingTo}
                renderValue={(v) => (v ? findLabel(LOOKING_TO_OPTIONS, v) : placeholder)}
                MenuProps={selectMenuProps}
                sx={selectSx}
                inputProps={{ 'aria-label': "I'm looking to", 'aria-required': true }}
              >
                {LOOKING_TO_OPTIONS.map((o) => (
                  <MenuItem key={o.value} value={o.value}>
                    {o.label}
                  </MenuItem>
                ))}
              </Select>
            </Box>
          </Box>

          {/* Step 2: I'm planning for */}
          <Box sx={{ display: 'flex', gap: 2.5, alignItems: 'flex-end' }}>
            <StepCircle step={2} completed={!!planningFor} showConnector />
            <Box sx={{ flex: 1 }}>
              <Typography
                variant="body1"
                sx={{
                  fontWeight: 600,
                  mb: 1,
                  color: lookingTo ? 'var(--fa-color-brand-700)' : 'text.disabled',
                }}
              >
                I&rsquo;m planning for
              </Typography>
              <Select
                value={planningFor}
                onChange={handlePlanningFor}
                displayEmpty
                disabled={step2Disabled}
                error={errs.planningFor}
                renderValue={(v) => (v ? findLabel(PLANNING_FOR_OPTIONS, v) : placeholder)}
                MenuProps={selectMenuProps}
                sx={selectSx}
                inputProps={{ 'aria-label': "I'm planning for", 'aria-required': true }}
              >
                {PLANNING_FOR_OPTIONS.map((o) => (
                  <MenuItem
                    key={o.value}
                    value={o.value}
                    disabled={isArrangeNow && o.value === 'myself'}
                  >
                    {o.label}
                  </MenuItem>
                ))}
              </Select>
            </Box>
          </Box>

          {/* Step 3: Type of funeral */}
          <Box sx={{ display: 'flex', gap: 2.5, alignItems: 'flex-end' }}>
            <StepCircle step={3} completed={!!funeralType} showConnector />
            <Box sx={{ flex: 1 }}>
              <Typography
                variant="body1"
                sx={{
                  fontWeight: 600,
                  mb: 1,
                  color: step3Disabled ? 'text.disabled' : 'var(--fa-color-brand-700)',
                }}
              >
                Type of funeral
              </Typography>
              <Select
                value={funeralType}
                onChange={handleFuneralType}
                displayEmpty
                disabled={step3Disabled}
                error={errs.funeralType}
                renderValue={(v) => (v ? findLabel(FUNERAL_TYPE_OPTIONS, v) : placeholder)}
                MenuProps={selectMenuProps}
                sx={selectSx}
                inputProps={{ 'aria-label': 'Type of funeral', 'aria-required': true }}
              >
                {FUNERAL_TYPE_OPTIONS.map((o) => (
                  <MenuItem key={o.value} value={o.value}>
                    {o.label}
                  </MenuItem>
                ))}
              </Select>
            </Box>
          </Box>

          {/* Step 4: Location */}
          <Box sx={{ display: 'flex', gap: 2.5, alignItems: 'flex-end' }}>
            <StepCircle step={4} completed={location.trim().length >= 3} />
            <Box sx={{ flex: 1 }}>
              <Typography
                variant="body1"
                sx={{
                  fontWeight: 600,
                  mb: 1,
                  color: step4Disabled ? 'text.disabled' : 'var(--fa-color-brand-700)',
                }}
              >
                Looking for providers in
              </Typography>
              <Input
                placeholder="Suburb or postcode"
                value={location}
                onChange={(e) => setLocation(e.target.value)}
                fullWidth
                disabled={step4Disabled}
                error={errs.location}
                inputProps={{ 'aria-label': 'Suburb or postcode', 'aria-required': true }}
                onKeyDown={(e) => {
                  if (e.key === 'Enter') handleSubmit();
                }}
                sx={{
                  bgcolor: 'var(--fa-color-surface-default, #fff)',
                  '& .MuiOutlinedInput-notchedOutline': {
                    borderColor: 'var(--fa-color-neutral-200)',
                    borderRadius: 'var(--fa-border-radius-md, 8px)',
                  },
                  '&:hover:not(.Mui-disabled) .MuiOutlinedInput-notchedOutline': {
                    borderColor: 'var(--fa-color-brand-400)',
                  },
                  '&.Mui-focused': { boxShadow: 'none' },
                  '&.Mui-focused .MuiOutlinedInput-notchedOutline': {
                    borderColor: 'var(--fa-color-brand-400)',
                    borderWidth: '1px',
                  },
                  '&.Mui-disabled': {
                    opacity: 0.6,
                    '& .MuiOutlinedInput-notchedOutline': {
                      borderStyle: 'dashed',
                    },
                  },
                  '&.Mui-error .MuiOutlinedInput-notchedOutline': {
                    borderColor: 'var(--fa-color-feedback-error-500, #d32f2f)',
                  },
                  '& .MuiOutlinedInput-input': {
                    py: '14px',
                    px: 2,
                    fontSize: '0.875rem',
                  },
                }}
              />
            </Box>
          </Box>
        </Box>

        {/* ── CTA ─────────────────────────────────────────────── */}
        <Divider sx={{ my: 4.5 }} />
        <Box>
          <Button
            variant="contained"
            size="large"
            fullWidth
            loading={loading}
            disabled={loading || location.trim().length < 3}
            onClick={handleSubmit}
          >
            Find Providers
          </Button>
          <Typography
            variant="captionSm"
            color="text.secondary"
            sx={{ textAlign: 'center', display: 'block', mt: 1.5 }}
          >
            Free to use &middot; No obligation
          </Typography>
        </Box>

        {/* Error hint — always rendered to maintain fixed height */}
        <Typography
          variant="captionSm"
          role={hasErrors ? 'alert' : undefined}
          sx={{
            mt: 1,
            minHeight: '1.25rem',
            textAlign: 'center',
            color: hasErrors ? 'error.main' : 'transparent',
            transition: 'color 200ms ease',
          }}
        >
          {errs.location
            ? 'Please enter a suburb or postcode'
            : errs.lookingTo
              ? 'Please tell us what you need help with'
              : errs.funeralType
                ? 'Please select a funeral type'
                : errs.planningFor
                  ? 'Please select who you are planning for'
                  : '\u00A0'}
        </Typography>
      </Box>
    );
  },
);

FuneralFinderV2.displayName = 'FuneralFinderV2';
export default FuneralFinderV2;
