'use client';
import { FunctionComponent } from 'react';
import ToggleButton from '@mui/material/ToggleButton';
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
import type { Gender } from '@/services/patients/types';

interface GenderToggleBaseProps {
  maleLabel: string;
  femaleLabel: string;
  /** Marks the group invalid (e.g. submitted without a choice). */
  error?: boolean;
  disabled?: boolean;
  ariaLabel?: string;
}

/** The default, booking-context shape — required male/female only, gender never defaulted. */
export interface GenderToggleRequiredProps extends GenderToggleBaseProps {
  allowAny?: false;
  /** Current selection; `null` means nothing chosen yet (gender is never defaulted). */
  value: Gender | null;
  /** Fires only with a concrete gender — deselecting is ignored so the field stays required. */
  onChange: (value: Gender) => void;
}

/** The opt-in search-context shape — adds a third "فرقی ندارد" (any) option. */
export interface GenderToggleAnyProps extends GenderToggleBaseProps {
  allowAny: true;
  /** Label for the "فرقی ندارد" / any-gender option (required when `allowAny`). */
  anyLabel: string;
  value: Gender | 'any' | null;
  onChange: (value: Gender | 'any') => void;
}

export type GenderToggleProps = GenderToggleRequiredProps | GenderToggleAnyProps;

/**
 * Required male/female toggle. Gender is **load-bearing** for same-gender caregiver matching
 * (search/booking), so it is never defaulted and cannot be deselected back to empty via the UI.
 * Labels are translated by the caller (labels are i18n keys off the code). The opt-in `allowAny`
 * mode (search's C1 facet) adds a third "فرقی ندارد" option **without** loosening the default
 * booking-context contract — omitting `allowAny` keeps the exact required male/female behaviour.
 * @component GenderToggle
 */
const GenderToggle: FunctionComponent<GenderToggleProps> = (props) => {
  const { maleLabel, femaleLabel, error = false, disabled = false, ariaLabel } = props;
  const allowAny = props.allowAny === true;

  const handleChange = (next: Gender | 'any' | null) => {
    if (!next) return;
    if (next === 'any' && !allowAny) return;
    // The two prop shapes are a discriminated union on `allowAny`; the runtime guard above already
    // enforces the invariant TS can't see through a plain union call, so this cast is safe.
    (props.onChange as (value: Gender | 'any') => void)(next);
  };

  return (
    <ToggleButtonGroup
      exclusive
      value={props.value}
      disabled={disabled}
      aria-label={ariaLabel}
      onChange={(_event, next: Gender | 'any' | null) => handleChange(next)}
      sx={{
        width: '100%',
        '& .MuiToggleButton-root': {
          flex: 1,
          py: 1.25,
          fontWeight: 700,
          borderColor: error ? 'var(--bal-error)' : undefined,
        },
      }}
    >
      <ToggleButton value="male" data-gender="male">
        {maleLabel}
      </ToggleButton>
      <ToggleButton value="female" data-gender="female">
        {femaleLabel}
      </ToggleButton>
      {allowAny ? (
        <ToggleButton value="any" data-gender="any">
          {(props as GenderToggleAnyProps).anyLabel}
        </ToggleButton>
      ) : null}
    </ToggleButtonGroup>
  );
};

export default GenderToggle;
