'use client';
import { ChangeEvent, FunctionComponent, useEffect, useRef } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { useForm, FormProvider, useWatch } from 'react-hook-form';
import { useSnackbar } from 'notistack';
import { Avatar, Box, MenuItem, Stack, Typography } from '@mui/material';
import {
  AccentCard,
  AppButton,
  AppIcon,
  AppLoading,
  FormSection,
  PageHeader,
  RhfChipSelect,
  RhfTextField,
  TrustBadge,
} from '@/components';
import { CONTENT_MAX_WIDTH } from '@/components/config';
import { ROUTES } from '@/constants';
import { digitsOnly } from '@/utils';
import { useNurseProfile, useUpsertNurseProfile, useUploadAvatar } from '@/services/profiles';
import type { NurseProfile } from '@/services/profiles/types';
import { useVerificationStatus } from '@/services/verification';
import { ownBadgeState, SPECIALTY_PRESETS } from '@/services/verification/types';

const MAX_YEARS = 80;
const MAX_YEARS_DIGITS = 2;
const OTHER_CODE = '__other';
const EDUCATION_LEVELS = ['diploma', 'associate', 'bachelor', 'master', 'doctorate'] as const;
const EDUCATION_FIELDS = ['nursing', 'midwifery', 'anesthesia', 'operating_room', 'public_health'] as const;

interface ProfileFormValues {
  avatarUrl: string | null;
  bio: string;
  years: string;
  educationLevel: string;
  educationLevelOther: string;
  educationField: string;
  educationFieldOther: string;
  specializations: string[];
}

function parseSpecializations(json: string): string[] {
  try {
    const parsed = JSON.parse(json);
    return Array.isArray(parsed) ? parsed.filter((item): item is string => typeof item === 'string') : [];
  } catch {
    return [];
  }
}

/**
 * Splits a stored free-text value into the (select code, "other" free-text) pair the form edits: a
 * value the preset list knows becomes the code, anything else becomes «سایر» + the raw text.
 */
function splitPreset(stored: string, presets: readonly string[]): { code: string; other: string } {
  if (presets.includes(stored)) return { code: stored, other: '' };
  return stored ? { code: OTHER_CODE, other: stored } : { code: '', other: '' };
}

/** Nurse profile bootstrap (B7 header): avatar + bio + experience + qualifications. */
export default function NurseProfilePage() {
  const { data: profile, isLoading } = useNurseProfile();
  if (isLoading) return <AppLoading />;
  return <NurseProfileForm initial={profile ?? null} />;
}

/**
 * The nurse's public-facing profile, rebuilt around three named questions instead of one undivided
 * column of inputs.
 *
 * What it replaced: a flat stack of avatar → bio → years → two selects → two conditional "other"
 * fields → a chip row → a save button, with no headings and no statement of what any of it was for.
 * The nurse could not tell which fields families actually see, which were required, or how much was
 * left — and every keystroke re-rendered the trust badge, the verification banner and the uploader
 * along with the field being typed into, because each input owned a `useState` at page level.
 *
 * Now: `FormSection` groups the fields into معرفی / تجربه و تحصیلات / تخصص‌ها, each saying who the
 * answer is for; react-hook-form owns the values so a keystroke re-renders one field; and validation
 * lives on the field it governs rather than in a hand-rolled block at the top of the submit handler.
 */
const NurseProfileForm: FunctionComponent<{ initial: NurseProfile | null }> = ({ initial }) => {
  const t = useTranslations('nurseProfile');
  const tv = useTranslations('verification');
  const tc = useTranslations('common');
  const locale = useLocale();
  const { enqueueSnackbar } = useSnackbar();
  const upsert = useUpsertNurseProfile();
  const uploadAvatar = useUploadAvatar();
  const { data: verificationStatus } = useVerificationStatus();
  const badgeState = ownBadgeState(verificationStatus);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const level = splitPreset(initial?.educationLevel ?? '', EDUCATION_LEVELS);
  const field = splitPreset(initial?.educationField ?? '', EDUCATION_FIELDS);

  const form = useForm<ProfileFormValues>({
    mode: 'onTouched',
    defaultValues: {
      avatarUrl: initial?.avatarUrl ?? null,
      bio: initial?.bio ?? '',
      years: initial ? String(initial.yearsOfExperience) : '',
      educationLevel: level.code,
      educationLevelOther: level.other,
      educationField: field.code,
      educationFieldOther: field.other,
      specializations: parseSpecializations(initial?.specializationsJson ?? '[]'),
    },
  });
  const { control, handleSubmit, setValue, getValues } = form;

  // Only these three drive conditional rendering, so they are the only fields worth subscribing the
  // page to — the rest re-render nothing but themselves.
  const avatarUrl = useWatch({ control, name: 'avatarUrl' });
  const educationLevel = useWatch({ control, name: 'educationLevel' });
  const educationField = useWatch({ control, name: 'educationField' });

  // A staged-but-unsaved avatar must never be silently discarded — warn on reload/tab-close.
  const avatarDirty = avatarUrl !== (initial?.avatarUrl ?? null);
  useEffect(() => {
    if (!avatarDirty) return;
    const handler = (event: BeforeUnloadEvent) => {
      event.preventDefault();
      // Chrome (and most engines) only show the native confirm dialog when returnValue is set.
      event.returnValue = '';
    };
    window.addEventListener('beforeunload', handler);
    return () => window.removeEventListener('beforeunload', handler);
  }, [avatarDirty]);

  const onFileSelected = (event: ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    event.target.value = '';
    if (!file) return;
    uploadAvatar.mutate(file, {
      onSuccess: (result) => setValue('avatarUrl', result.url, { shouldDirty: true }),
      onError: () => enqueueSnackbar(t('avatar_upload_error'), { variant: 'error' }),
    });
  };

  const save = (values: ProfileFormValues) => {
    const resolvedLevel =
      values.educationLevel === OTHER_CODE ? values.educationLevelOther.trim() : values.educationLevel;
    const resolvedField =
      values.educationField === OTHER_CODE ? values.educationFieldOther.trim() : values.educationField;

    upsert.mutate(
      {
        bio: values.bio.trim(),
        yearsOfExperience: values.years.trim() === '' ? 0 : Number(values.years),
        educationLevel: resolvedLevel,
        educationField: resolvedField,
        specializationsJson: JSON.stringify(values.specializations),
        avatarUrl: values.avatarUrl,
      },
      {
        onSuccess: () => {
          enqueueSnackbar(t('saved'), { variant: 'success' });
          // Re-baseline so the beforeunload guard and `isDirty` stop reporting saved work as unsaved.
          form.reset(getValues());
        },
        onError: () => enqueueSnackbar(t('save_error'), { variant: 'error' }),
      },
    );
  };

  return (
    <FormProvider {...form}>
      <Box
        component="form"
        noValidate
        onSubmit={handleSubmit(save)}
        sx={{ display: 'flex', flexDirection: 'column', gap: 2.5, maxWidth: CONTENT_MAX_WIDTH, mx: 'auto', width: '100%' }}
      >
        <PageHeader title={t('title')} subtitle={t('subtitle')} meta={<TrustBadge state={badgeState} />} />

        {/* Blocked-until-verified nudge — shown until the aggregate is approved (incl. the expired state). */}
        {badgeState !== 'verified' ? (
          <AccentCard tone="warning" padding="sm">
            <Stack sx={{ gap: 1 }}>
              <Stack direction="row" sx={{ gap: 1, alignItems: 'center' }}>
                <AppIcon icon="warning" size={20} color="var(--bal-warning)" />
                <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
                  {t('unverified_title')}
                </Typography>
              </Stack>
              <Typography variant="body2" sx={{ color: 'text.secondary' }}>
                {t('unverified_body')}
              </Typography>
              <AppButton
                color="primary"
                variant="text"
                endIcon="forward"
                to={`/${locale}${ROUTES.NURSE_VERIFICATION}`}
                sx={{ alignSelf: 'flex-start' }}
              >
                {t('unverified_cta')}
              </AppButton>
            </Stack>
          </AccentCard>
        ) : null}

        <FormSection title={t('section_intro_title')} description={t('section_intro_description')} icon="account">
          <Stack direction="row" sx={{ gap: 2, alignItems: 'center' }}>
            <Avatar src={avatarUrl ?? undefined} sx={{ width: 64, height: 64, bgcolor: 'var(--bal-primary-soft)' }}>
              {avatarUrl ? null : <AppIcon icon="account" size={32} color="var(--bal-primary)" />}
            </Avatar>
            <Stack sx={{ gap: 0.5, minWidth: 0 }}>
              <Typography variant="caption" sx={{ color: 'text.secondary' }}>
                {t('photo_hint')}
              </Typography>
              <AppButton
                variant="outlined"
                color="primary"
                startIcon="camera"
                onClick={() => fileInputRef.current?.click()}
                disabled={uploadAvatar.isPending}
                sx={{ alignSelf: 'flex-start' }}
              >
                {uploadAvatar.isPending ? t('uploading') : t('upload')}
              </AppButton>
              <input ref={fileInputRef} type="file" accept="image/*" hidden onChange={onFileSelected} />
            </Stack>
          </Stack>

          <RhfTextField<ProfileFormValues>
            name="bio"
            label={t('bio')}
            helperText={t('bio_hint')}
            multiline
            minRows={3}
            fullWidth
          />
        </FormSection>

        <FormSection
          title={t('section_experience_title')}
          description={t('section_experience_description')}
          icon="license"
        >
          <RhfTextField<ProfileFormValues>
            name="years"
            label={t('years')}
            transform={(raw) => digitsOnly(raw).slice(0, MAX_YEARS_DIGITS)}
            rules={{
              validate: (value) => {
                const trimmed = String(value ?? '').trim();
                if (trimmed === '') return true;
                const parsed = Number(trimmed);
                return (Number.isInteger(parsed) && parsed >= 0 && parsed <= MAX_YEARS) || t('years_invalid');
              },
            }}
            slotProps={{ htmlInput: { dir: 'ltr', inputMode: 'numeric', style: { textAlign: 'start' } } }}
            sx={{ maxWidth: 200 }}
          />

          <Stack direction={{ xs: 'column', sm: 'row' }} sx={{ gap: 2 }}>
            <RhfTextField<ProfileFormValues> name="educationLevel" select label={t('education_level_label')} fullWidth>
              {EDUCATION_LEVELS.map((code) => (
                <MenuItem key={code} value={code}>
                  {t(`education_level_${code}`)}
                </MenuItem>
              ))}
              <MenuItem value={OTHER_CODE}>{t('education_other')}</MenuItem>
            </RhfTextField>
            <RhfTextField<ProfileFormValues> name="educationField" select label={t('education_field_label')} fullWidth>
              {EDUCATION_FIELDS.map((code) => (
                <MenuItem key={code} value={code}>
                  {t(`education_field_${code}`)}
                </MenuItem>
              ))}
              <MenuItem value={OTHER_CODE}>{t('education_other')}</MenuItem>
            </RhfTextField>
          </Stack>

          {educationLevel === OTHER_CODE ? (
            <RhfTextField<ProfileFormValues>
              name="educationLevelOther"
              label={t('education_level_other_label')}
              rules={{ required: t('education_other_required') }}
              fullWidth
            />
          ) : null}
          {educationField === OTHER_CODE ? (
            <RhfTextField<ProfileFormValues>
              name="educationFieldOther"
              label={t('education_field_other_label')}
              rules={{ required: t('education_other_required') }}
              fullWidth
            />
          ) : null}
        </FormSection>

        <FormSection
          title={t('specializations_label')}
          description={t('section_specializations_description')}
          icon="clinical"
          optional
          optionalLabel={tc('optional')}
        >
          <RhfChipSelect<ProfileFormValues>
            name="specializations"
            options={SPECIALTY_PRESETS.map((code) => ({
              code,
              label: tv.has(`specialty_${code}`) ? tv(`specialty_${code}`) : code,
            }))}
            allowCustomValues
          />
        </FormSection>

        <Stack direction="row" sx={{ gap: 1, alignItems: 'center', flexWrap: 'wrap' }}>
          <AppButton type="submit" color="primary" variant="contained" disabled={upsert.isPending}>
            {upsert.isPending ? tc('saving') : t('save')}
          </AppButton>
          <AppButton variant="text" color="primary" startIcon="account" to={`/${locale}${ROUTES.NURSE_PROFILE_PREVIEW}`}>
            {t('preview_cta')}
          </AppButton>
        </Stack>

        <Typography variant="caption" sx={{ color: 'text.secondary' }}>
          {t('deferred_services')}
        </Typography>
      </Box>
    </FormProvider>
  );
};
