'use client';
import { FunctionComponent, useState } from 'react';
import { useTranslations } from 'next-intl';
import FormLabel from '@mui/material/FormLabel';
import Stack from '@mui/material/Stack';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import { AppButton } from '@/components/common';
import GenderToggle from '@/components/GenderToggle';
import ConditionChips from '@/components/ConditionChips';
import RelationSelect from '@/components/RelationSelect';
import { digitsOnly } from '@/utils';
import { CONDITION_CODES, RELATION_CODES } from '@/services/patients/constants';
import { ageToBirthDate, birthDateToAge } from '@/services/patients/age';
import type { ConditionCode, CreatePatientInput, Gender, Patient, Relation } from '@/services/patients/types';

const MAX_AGE = 120;

export interface PatientFormProps {
  /** Prefill for edit, or a relation carried from the onboarding relation step. */
  initial?: Partial<Pick<Patient, 'displayName' | 'birthDate' | 'gender' | 'conditions' | 'relation'>>;
  /** Show the relation picker (E1 add/edit). Onboarding hides it — A3 already chose the relation. */
  showRelation?: boolean;
  submitLabel: string;
  submitting?: boolean;
  onSubmit: (input: CreatePatientInput) => void;
  onCancel?: () => void;
  cancelLabel?: string;
}

// A single full-name field (per the wireframe) maps to the contract's first/last/display.
function splitName(fullName: string): Pick<CreatePatientInput, 'displayName' | 'firstName' | 'lastName'> {
  const displayName = fullName.trim();
  const parts = displayName.split(/\s+/);
  const firstName = parts[0] ?? '';
  const lastName = parts.slice(1).join(' ') || firstName;
  return { displayName, firstName, lastName };
}

/**
 * The A4 patient form — full name, age, **required** gender, optional condition chips, and
 * (for E1) the relation. Reused for create and edit. Gender is required and never defaulted;
 * age maps to `birthDate`. Strings come from the `onboarding` namespace.
 * @component PatientForm
 */
const PatientForm: FunctionComponent<PatientFormProps> = ({
  initial,
  showRelation = false,
  submitLabel,
  submitting = false,
  onSubmit,
  onCancel,
  cancelLabel,
}) => {
  const t = useTranslations('onboarding');

  const [fullName, setFullName] = useState(initial?.displayName ?? '');
  const [age, setAge] = useState(() => {
    const initialAge = birthDateToAge(initial?.birthDate);
    return initialAge == null ? '' : String(initialAge);
  });
  const [gender, setGender] = useState<Gender | null>(initial?.gender ?? null);
  const [conditions, setConditions] = useState<string[]>(initial?.conditions ?? []);
  const [relation, setRelation] = useState<Relation | null>(initial?.relation ?? null);

  const [nameError, setNameError] = useState(false);
  const [ageError, setAgeError] = useState(false);
  const [genderError, setGenderError] = useState(false);

  const conditionOptions = CONDITION_CODES.map((code) => ({ code, label: t(`condition_${code}`) }));
  const relationOptions = RELATION_CODES.map((code) => ({ code, label: t(`relation_${code}`) }));

  const handleSubmit = () => {
    const name = fullName.trim();
    const ageNum = Number(digitsOnly(age));
    const nameInvalid = name.length === 0;
    const ageInvalid = age.trim().length === 0 || !Number.isInteger(ageNum) || ageNum < 0 || ageNum > MAX_AGE;
    const genderInvalid = gender == null;

    setNameError(nameInvalid);
    setAgeError(ageInvalid);
    setGenderError(genderInvalid);
    if (nameInvalid || ageInvalid || genderInvalid) return;

    onSubmit({
      ...splitName(name),
      birthDate: ageToBirthDate(ageNum),
      gender: gender as Gender,
      bloodType: null,
      initialMedicalNotes: null,
      relation,
      conditions: conditions as ConditionCode[],
    });
  };

  return (
    <Stack sx={{ gap: 2.5 }}>
      <TextField
        label={t('name_label')}
        value={fullName}
        onChange={(event) => {
          setFullName(event.target.value);
          if (nameError) setNameError(false);
        }}
        error={nameError}
        helperText={nameError ? t('name_required') : undefined}
        fullWidth
      />

      <TextField
        label={t('age_label')}
        value={age}
        onChange={(event) => {
          setAge(digitsOnly(event.target.value).slice(0, 3));
          if (ageError) setAgeError(false);
        }}
        error={ageError}
        helperText={ageError ? t('age_invalid') : undefined}
        slotProps={{ htmlInput: { dir: 'ltr', inputMode: 'numeric', style: { textAlign: 'start' } } }}
        sx={{ maxWidth: 160 }}
      />

      <Stack sx={{ gap: 1 }}>
        <FormLabel error={genderError}>{t('gender_label')}</FormLabel>
        <GenderToggle
          value={gender}
          onChange={(next) => {
            setGender(next);
            if (genderError) setGenderError(false);
          }}
          maleLabel={t('gender_male')}
          femaleLabel={t('gender_female')}
          error={genderError}
          ariaLabel={t('gender_label')}
        />
        {genderError ? (
          <Typography variant="caption" sx={{ color: 'var(--bal-error)' }}>
            {t('gender_required')}
          </Typography>
        ) : null}
      </Stack>

      <Stack sx={{ gap: 1 }}>
        <FormLabel>{t('conditions_label')}</FormLabel>
        <Typography variant="caption" sx={{ color: 'text.secondary' }}>
          {t('conditions_hint')}
        </Typography>
        <ConditionChips options={conditionOptions} value={conditions} onChange={setConditions} />
      </Stack>

      {showRelation ? (
        <Stack sx={{ gap: 1 }}>
          <FormLabel>{t('relation_title')}</FormLabel>
          <RelationSelect
            options={relationOptions}
            value={relation}
            onChange={(code) => setRelation(code as Relation)}
          />
        </Stack>
      ) : null}

      <Stack direction="row" sx={{ gap: 1, justifyContent: 'flex-end' }}>
        {onCancel ? (
          <AppButton variant="text" onClick={onCancel} disabled={submitting} sx={{ m: 0 }}>
            {cancelLabel}
          </AppButton>
        ) : null}
        <AppButton
          color="primary"
          variant="contained"
          onClick={handleSubmit}
          disabled={submitting}
          sx={{ m: 0 }}
        >
          {submitLabel}
        </AppButton>
      </Stack>
    </Stack>
  );
};

export default PatientForm;
