import React from 'react';
import MuiToggleButton from '@mui/material/ToggleButton';
import MuiToggleButtonGroup from '@mui/material/ToggleButtonGroup';
import type { ToggleButtonGroupProps as MuiToggleButtonGroupProps } from '@mui/material/ToggleButtonGroup';
import FormControl from '@mui/material/FormControl';
import FormLabel from '@mui/material/FormLabel';
import FormHelperText from '@mui/material/FormHelperText';
import Box from '@mui/material/Box';
import type { SxProps, Theme } from '@mui/material/styles';
import { Typography } from '../Typography';

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

/** A single option in the toggle button group */
export interface ToggleOption {
  /** Unique value for this option */
  value: string;
  /** Display label */
  label: string;
  /** Optional description shown below the label */
  description?: string;
  /** Whether this option is disabled */
  disabled?: boolean;
}

/** Props for the FA ToggleButtonGroup component */
export interface ToggleButtonGroupProps extends Omit<
  MuiToggleButtonGroupProps,
  'onChange' | 'children'
> {
  /** Available options to choose from */
  options: ToggleOption[];
  /** Currently selected value (single-select) */
  value: string | null;
  /** Callback fired when the selection changes */
  onChange: (value: string | null) => void;
  /** Fieldset legend / visible label above the group */
  label?: string;
  /** Helper text below the group */
  helperText?: string;
  /** Error state — shows error styling and uses helperText as error message */
  error?: boolean;
  /** Whether a selection is required */
  required?: boolean;
  /** Text alignment inside each option button */
  align?: 'start' | 'center';
  /** Layout direction for the button group */
  direction?: 'row' | 'column';
  /** MUI sx prop for the root FormControl */
  sx?: SxProps<Theme>;
}

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

/**
 * Exclusive toggle button group for the FA design system.
 *
 * Renders a set of toggle buttons in a horizontal row (stacks on narrow
 * viewports). Used for binary or small-set choices in the arrangement
 * wizard (e.g. "Myself / Someone else", "Yes / No").
 *
 * Wraps MUI ToggleButtonGroup in a FormControl with fieldset semantics,
 * external label, helper/error text, and FA brand styling.
 *
 * Keyboard: Arrow keys cycle options, Space/Enter selects. Tab moves
 * between groups.
 *
 * Usage:
 * ```tsx
 * <ToggleButtonGroup
 *   label="Who is this funeral being arranged for?"
 *   options={[
 *     { value: 'myself', label: 'Myself', description: 'I want to plan my own funeral' },
 *     { value: 'someone', label: 'Someone else', description: 'I am arranging for a family member or friend' },
 *   ]}
 *   value={forWhom}
 *   onChange={setForWhom}
 * />
 * ```
 */
export const ToggleButtonGroup = React.forwardRef<HTMLFieldSetElement, ToggleButtonGroupProps>(
  (
    {
      options,
      value,
      onChange,
      label,
      helperText,
      error = false,
      required = false,
      align = 'start',
      direction = 'row',
      fullWidth,
      size = 'large',
      sx,
      ...groupProps
    },
    ref,
  ) => {
    const handleChange = (_event: React.MouseEvent<HTMLElement>, newValue: string | null) => {
      // Enforce exclusive selection — don't allow deselect
      if (newValue !== null) {
        onChange(newValue);
      }
    };

    return (
      <FormControl
        ref={ref}
        component="fieldset"
        error={error}
        required={required}
        fullWidth={fullWidth}
        sx={[...(Array.isArray(sx) ? sx : [sx])]}
      >
        {label && (
          <FormLabel
            component="legend"
            sx={{
              color: 'text.primary',
              fontWeight: 600,
              fontSize: '1rem',
              mb: 2,
              '&.Mui-focused': { color: 'text.primary' },
              '&.Mui-error': { color: 'text.primary' },
            }}
          >
            {label}
          </FormLabel>
        )}

        <MuiToggleButtonGroup
          exclusive
          value={value}
          onChange={handleChange}
          fullWidth={fullWidth}
          size={size}
          aria-label={label}
          sx={{
            gap: 2,
            ...(direction === 'column' && { flexDirection: 'column' }),
            // Remove MUI's connected-button styling (grouped borders)
            '& .MuiToggleButtonGroup-grouped': {
              border: '2px solid',
              borderColor: 'var(--fa-color-neutral-200)',
              borderRadius: (theme: Theme) => `${theme.shape.borderRadius}px !important`,
              '&:not(:first-of-type)': {
                borderLeft: '2px solid',
                borderColor: 'var(--fa-color-neutral-200)',
                marginLeft: 0,
                ...(direction === 'column' && { marginTop: 0 }),
              },
              '&.Mui-selected': {
                borderColor: 'primary.main',
              },
            },
          }}
          {...groupProps}
        >
          {options.map((option) => (
            <MuiToggleButton
              key={option.value}
              value={option.value}
              disabled={option.disabled}
              sx={{
                flex: direction === 'row' ? 1 : undefined,
                textTransform: 'none',
                flexDirection: 'column',
                alignItems: align === 'center' ? 'center' : 'flex-start',
                justifyContent: 'flex-start',
                gap: 0.5,
                py: option.description ? 2 : 1.5,
                px: 3,
                bgcolor: 'var(--fa-color-neutral-100)',
                color: 'text.primary',
                transition: (theme: Theme) =>
                  theme.transitions.create(['background-color', 'border-color', 'box-shadow'], {
                    duration: theme.transitions.duration.short,
                  }),

                '&:hover': {
                  bgcolor: 'var(--fa-color-neutral-200)',
                },

                // Selected state — brand styling
                '&.Mui-selected': {
                  bgcolor: 'var(--fa-color-brand-50)',
                  borderColor: 'primary.main',
                  color: 'text.primary',
                  '&:hover': {
                    bgcolor: 'var(--fa-color-brand-100)',
                  },
                },

                // Error border — copper, not red (D034)
                ...(error && {
                  borderColor: 'var(--fa-color-text-brand)',
                  '&.Mui-selected': {
                    borderColor: 'primary.main',
                  },
                }),

                // Focus ring
                '&:focus-visible': {
                  outline: '2px solid var(--fa-color-interactive-focus)',
                  outlineOffset: '2px',
                },

                // Disabled
                '&.Mui-disabled': {
                  opacity: 0.4,
                },
              }}
            >
              <Box
                component="span"
                sx={{ fontWeight: 600, fontSize: size === 'large' ? '1rem' : '0.875rem' }}
              >
                {option.label}
              </Box>
              {option.description && (
                <Typography
                  variant="body2"
                  color="text.primary"
                  component="span"
                  sx={{ fontWeight: 400, lineHeight: 1.4 }}
                >
                  {option.description}
                </Typography>
              )}
            </MuiToggleButton>
          ))}
        </MuiToggleButtonGroup>

        {helperText && <FormHelperText sx={{ mt: 1, mx: 0 }}>{helperText}</FormHelperText>}
      </FormControl>
    );
  },
);

ToggleButtonGroup.displayName = 'ToggleButtonGroup';
export default ToggleButtonGroup;
