'use client';
import { ChangeEvent, FunctionComponent, useEffect, useRef, useState } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { useSnackbar } from 'notistack';
import { Avatar, Box, Chip, MenuItem, Paper, Stack, TextField, Typography } from '@mui/material';
import { AppButton, AppIcon, AppLoading, TrustBadge } from '@/components';
import { ROUTES } from '@/constants';
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 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;

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 [];
  }
}

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

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 [avatarUrl, setAvatarUrl] = useState<string | null>(initial?.avatarUrl ?? null);
  const [bio, setBio] = useState(initial?.bio ?? '');
  const [years, setYears] = useState(initial ? String(initial.yearsOfExperience) : '');
  const [yearsError, setYearsError] = useState(false);

  const initialLevel = initial?.educationLevel ?? '';
  const initialField = initial?.educationField ?? '';
  const [educationLevel, setEducationLevel] = useState(
    (EDUCATION_LEVELS as readonly string[]).includes(initialLevel) ? initialLevel : initialLevel ? OTHER_CODE : '',
  );
  const [educationLevelOther, setEducationLevelOther] = useState(
    (EDUCATION_LEVELS as readonly string[]).includes(initialLevel) ? '' : initialLevel,
  );
  const [educationField, setEducationField] = useState(
    (EDUCATION_FIELDS as readonly string[]).includes(initialField) ? initialField : initialField ? OTHER_CODE : '',
  );
  const [educationFieldOther, setEducationFieldOther] = useState(
    (EDUCATION_FIELDS as readonly string[]).includes(initialField) ? '' : initialField,
  );
  const [specializations, setSpecializations] = useState<string[]>(
    parseSpecializations(initial?.specializationsJson ?? '[]'),
  );

  // 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 pickFile = () => fileInputRef.current?.click();

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

  const toggleSpecialty = (value: string) =>
    setSpecializations((prev) => (prev.includes(value) ? prev.filter((item) => item !== value) : [...prev, value]));

  const handleSave = () => {
    const trimmed = years.trim();
    const yearsNum = trimmed === '' ? 0 : Number(trimmed);
    const yearsInvalid = !Number.isInteger(yearsNum) || yearsNum < 0 || yearsNum > MAX_YEARS;
    setYearsError(yearsInvalid);
    if (yearsInvalid) return;

    const resolvedLevel = educationLevel === OTHER_CODE ? educationLevelOther.trim() : educationLevel;
    const resolvedField = educationField === OTHER_CODE ? educationFieldOther.trim() : educationField;

    upsert.mutate(
      {
        bio: bio.trim(),
        yearsOfExperience: yearsNum,
        educationLevel: resolvedLevel,
        educationField: resolvedField,
        specializationsJson: JSON.stringify(specializations),
        avatarUrl,
      },
      {
        onSuccess: () => enqueueSnackbar(t('saved'), { variant: 'success' }),
        onError: () => enqueueSnackbar(t('save_error'), { variant: 'error' }),
      },
    );
  };

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3, maxWidth: 560 }}>
      <Box>
        <Stack direction="row" sx={{ gap: 1.5, alignItems: 'center', flexWrap: 'wrap' }}>
          <Typography variant="h5" component="h1">
            {t('title')}
          </Typography>
          {/* The public trust signal on the nurse's own profile — the same badge f6 reuses in search. */}
          <TrustBadge state={badgeState} />
        </Stack>
        <Typography variant="body2" sx={{ color: 'text.secondary' }}>
          {t('subtitle')}
        </Typography>
      </Box>

      {/* Blocked-until-verified banner — shown until the aggregate is approved (incl. the expired state). */}
      {badgeState !== 'verified' ? (
        <Paper
          elevation={0}
          sx={{ p: 2, borderRadius: 2, border: '1px solid', borderColor: 'divider', borderInlineStartWidth: 4, borderInlineStartColor: 'var(--bal-warning)' }}
        >
          <Stack direction="row" sx={{ gap: 1.5, alignItems: 'flex-start' }}>
            <AppIcon icon="warning" size={24} color="var(--bal-warning)" />
            <Stack sx={{ gap: 1, flexGrow: 1 }}>
              <Box>
                <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
                  {t('unverified_title')}
                </Typography>
                <Typography variant="body2" sx={{ color: 'text.secondary' }}>
                  {t('unverified_body')}
                </Typography>
              </Box>
              <AppButton
                color="primary"
                variant="outlined"
                to={`/${locale}${ROUTES.NURSE_VERIFICATION}`}
                sx={{ alignSelf: 'flex-start' }}
              >
                {t('unverified_cta')}
              </AppButton>
            </Stack>
          </Stack>
        </Paper>
      ) : null}

      <Stack direction="row" sx={{ gap: 2, alignItems: 'center' }}>
        <Avatar src={avatarUrl ?? undefined} sx={{ width: 72, height: 72, bgcolor: 'var(--bal-primary-soft)' }}>
          {avatarUrl ? null : <AppIcon icon="account" size={36} color="var(--bal-primary)" />}
        </Avatar>
        <Stack sx={{ gap: 0.5 }}>
          <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
            {t('photo')}
          </Typography>
          <Typography variant="caption" sx={{ color: 'text.secondary' }}>
            {t('photo_hint')}
          </Typography>
          <AppButton
            variant="outlined"
            color="primary"
            startIcon="camera"
            onClick={pickFile}
            disabled={uploadAvatar.isPending}
            sx={{ mt: 0.5, alignSelf: 'flex-start' }}
          >
            {uploadAvatar.isPending ? t('uploading') : t('upload')}
          </AppButton>
          <input ref={fileInputRef} type="file" accept="image/*" hidden onChange={onFileSelected} />
        </Stack>
      </Stack>

      <TextField
        label={t('bio')}
        value={bio}
        onChange={(e) => setBio(e.target.value)}
        helperText={t('bio_hint')}
        multiline
        minRows={3}
        fullWidth
      />

      <TextField
        label={t('years')}
        value={years}
        onChange={(e) => {
          setYears(e.target.value.replace(/\D/g, '').slice(0, 2));
          if (yearsError) setYearsError(false);
        }}
        error={yearsError}
        helperText={yearsError ? t('years_invalid') : undefined}
        slotProps={{ htmlInput: { dir: 'ltr', inputMode: 'numeric', style: { textAlign: 'start' } } }}
        sx={{ maxWidth: 200 }}
      />

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

      {educationLevel === OTHER_CODE ? (
        <TextField
          label={t('education_level_other_label')}
          value={educationLevelOther}
          onChange={(e) => setEducationLevelOther(e.target.value)}
          fullWidth
        />
      ) : null}
      {educationField === OTHER_CODE ? (
        <TextField
          label={t('education_field_other_label')}
          value={educationFieldOther}
          onChange={(e) => setEducationFieldOther(e.target.value)}
          fullWidth
        />
      ) : null}

      <Stack sx={{ gap: 1 }}>
        <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
          {t('specializations_label')}
        </Typography>
        <Stack direction="row" sx={{ gap: 1, flexWrap: 'wrap' }}>
          {SPECIALTY_PRESETS.map((code) => {
            const selected = specializations.includes(code);
            return (
              <Chip
                key={code}
                label={tv.has(`specialty_${code}`) ? tv(`specialty_${code}`) : code}
                onClick={() => toggleSpecialty(code)}
                variant={selected ? 'filled' : 'outlined'}
                sx={{
                  fontWeight: 500,
                  backgroundColor: selected ? 'var(--bal-primary)' : 'transparent',
                  color: selected ? 'var(--bal-primary-contrast)' : 'var(--bal-primary)',
                  borderColor: 'var(--bal-primary)',
                }}
              />
            );
          })}
        </Stack>
      </Stack>

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

      <AppButton
        variant="text"
        color="primary"
        startIcon="account"
        to={`/${locale}${ROUTES.NURSE_PROFILE_PREVIEW}`}
        sx={{ alignSelf: 'flex-start' }}
      >
        {t('preview_cta')}
      </AppButton>

      <AppButton
        color="primary"
        variant="contained"
        onClick={handleSave}
        disabled={upsert.isPending}
        sx={{ alignSelf: 'flex-start' }}
      >
        {upsert.isPending ? tc('saving') : t('save')}
      </AppButton>
    </Box>
  );
};
