// Profile page — static SPA, no import/export, globals: React, useT, useLang, navigateTo, useAuth, PBNav, PBFooter, PBLogo
// Wrapped by PrivateRoute in index.html (route #/profile). Uses direct zh/en ternaries for new copy
// so the leader's i18n PR can land independently (same pattern as page-booking.jsx).

const ProfilePage = () => {
  const lang = useLang();
  const { user, refresh } = useAuth();

  // Local form state — initialized from user once it's available
  const [form, setForm] = React.useState({
    name: '',
    phone: '',
    studentType: 'gaokao',
    gradeYear: '',
  });
  const [errors, setErrors] = React.useState({});
  const [banner, setBanner] = React.useState(null);
  const [success, setSuccess] = React.useState(null);
  const [submitting, setSubmitting] = React.useState(false);
  const [hydrated, setHydrated] = React.useState(false);
  const successTimerRef = React.useRef(null);

  // Change-password form state (M1.4) — kept separate from profile form so
  // the two flows don't share submitting / banner / success bus.
  const [pwForm, setPwForm] = React.useState({
    currentPassword: '',
    newPassword: '',
    confirmPassword: '',
  });
  const [pwErrors, setPwErrors] = React.useState({});
  const [pwBanner, setPwBanner] = React.useState(null);
  const [pwSuccess, setPwSuccess] = React.useState(null);
  const [pwSubmitting, setPwSubmitting] = React.useState(false);
  const pwSuccessTimerRef = React.useRef(null);

  // Pre-fill from user once it arrives (and re-sync after refresh())
  React.useEffect(() => {
    if (!user) return;
    const profile = user.profile || {};
    setForm({
      name: user.name || '',
      phone: user.phone || '',
      studentType: profile.studentType || 'gaokao',
      gradeYear: profile.gradeYear || '',
    });
    setHydrated(true);
  }, [user]);

  // Cleanup success timers on unmount
  React.useEffect(() => {
    return () => {
      if (successTimerRef.current) {
        clearTimeout(successTimerRef.current);
        successTimerRef.current = null;
      }
      if (pwSuccessTimerRef.current) {
        clearTimeout(pwSuccessTimerRef.current);
        pwSuccessTimerRef.current = null;
      }
    };
  }, []);

  const setField = (k) => (e) => {
    const v = e.target.value;
    setForm((f) => ({ ...f, [k]: v }));
    setErrors((er) => ({ ...er, [k]: undefined }));
  };

  const setStudentType = (type) => {
    setForm((f) => ({ ...f, studentType: type }));
    setErrors((er) => ({ ...er, studentType: undefined }));
  };

  // Map server-side error codes to user-facing strings (zh/en)
  const errMessage = (code) => {
    const m = {
      required: lang === 'zh' ? '此项必填' : 'Required',
      name_invalid: lang === 'zh' ? '请填写有效的姓名' : 'Please enter a valid name',
      phone_invalid: lang === 'zh' ? '电话号码格式不正确' : 'Invalid phone number',
      invalid: lang === 'zh' ? '取值无效' : 'Invalid value',
      unknown: lang === 'zh' ? '未知错误' : 'Unknown error',
    };
    return m[code] || m.unknown;
  };

  const onSubmit = async (e) => {
    e.preventDefault();
    setBanner(null);
    setSuccess(null);
    setErrors({});

    // Light client-side validation (server is the source of truth)
    const e0 = {};
    if (!form.name || !form.name.trim()) {
      e0.name = lang === 'zh' ? '此项必填' : 'Required';
    }
    if (form.phone && !/^[\d\s+\-()]{6,20}$/.test(form.phone)) {
      e0.phone = lang === 'zh' ? '电话号码格式不正确' : 'Invalid phone number';
    }
    if (!form.gradeYear) {
      e0.gradeYear = lang === 'zh' ? '此项必填' : 'Required';
    }
    if (Object.keys(e0).length > 0) {
      setErrors(e0);
      return;
    }

    setSubmitting(true);
    try {
      const payload = {
        name: form.name.trim(),
        phone: form.phone || '',
        profile: {
          studentType: form.studentType,
          gradeYear: form.gradeYear,
        },
      };
      const r = await fetch('/api/user/update-profile', {
        method: 'PATCH',
        credentials: 'same-origin',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });

      if (r.ok) {
        try { await refresh(); } catch (_) { /* swallow — UI still shows success */ }
        setSuccess(lang === 'zh' ? '已保存' : 'Saved');
        if (successTimerRef.current) clearTimeout(successTimerRef.current);
        successTimerRef.current = setTimeout(() => {
          setSuccess(null);
          successTimerRef.current = null;
        }, 3000);
        return;
      }

      // Try to parse JSON body for fields/codes
      let data = {};
      try { data = await r.json(); } catch (_) { data = {}; }

      if (r.status === 401) {
        navigateTo('/login');
        return;
      }
      if (r.status === 400 && data && data.fields) {
        const mapped = {};
        Object.entries(data.fields).forEach(([k, code]) => {
          // Server may report nested keys like 'profile.gradeYear'
          const local = k.startsWith('profile.') ? k.slice('profile.'.length) : k;
          mapped[local] = errMessage(code);
        });
        setErrors(mapped);
        setBanner(lang === 'zh' ? '请检查表单' : 'Please review the form');
        return;
      }
      // 500 / unexpected
      setBanner(lang === 'zh' ? '保存失败,请稍后再试' : 'Save failed, please try again later');
    } catch (err) {
      // Network error
      setBanner(lang === 'zh' ? '网络错误,请检查连接' : 'Network error, please check your connection');
    } finally {
      setSubmitting(false);
    }
  };

  // Change-password handlers
  const setPwField = (k) => (e) => {
    const v = e.target.value;
    setPwForm((f) => ({ ...f, [k]: v }));
    setPwErrors((er) => ({ ...er, [k]: undefined }));
  };

  const pwErrMessage = (code) => {
    const m = {
      required: lang === 'zh' ? '此项必填' : 'Required',
      password_short: lang === 'zh' ? '密码至少 8 位' : 'Password must be at least 8 characters',
      password_weak: lang === 'zh' ? '密码需包含字母与数字' : 'Password must contain letters and digits',
      password_mismatch: lang === 'zh' ? '两次密码不一致' : 'Passwords do not match',
      same_as_old: lang === 'zh' ? '新密码不能与当前密码相同' : 'New password must differ from the current one',
      wrong_password: lang === 'zh' ? '当前密码不正确' : 'Current password is incorrect',
      unknown: lang === 'zh' ? '未知错误' : 'Unknown error',
    };
    return m[code] || m.unknown;
  };

  const onChangePassword = async (e) => {
    e.preventDefault();
    setPwBanner(null);
    setPwSuccess(null);
    setPwErrors({});

    // Light client-side validation (server is authoritative)
    const e0 = {};
    if (!pwForm.currentPassword) e0.currentPassword = pwErrMessage('required');
    if (!pwForm.newPassword) {
      e0.newPassword = pwErrMessage('required');
    } else if (pwForm.newPassword.length < 8) {
      e0.newPassword = pwErrMessage('password_short');
    } else if (!/[A-Za-z]/.test(pwForm.newPassword) || !/\d/.test(pwForm.newPassword)) {
      e0.newPassword = pwErrMessage('password_weak');
    }
    if (pwForm.newPassword !== pwForm.confirmPassword) {
      e0.confirmPassword = pwErrMessage('password_mismatch');
    }
    if (Object.keys(e0).length > 0) {
      setPwErrors(e0);
      return;
    }

    setPwSubmitting(true);
    try {
      const r = await fetch('/api/auth/change-password', {
        method: 'POST',
        credentials: 'same-origin',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(pwForm),
      });

      if (r.ok) {
        setPwForm({ currentPassword: '', newPassword: '', confirmPassword: '' });
        setPwSuccess(lang === 'zh' ? '密码已更新' : 'Password updated');
        if (pwSuccessTimerRef.current) clearTimeout(pwSuccessTimerRef.current);
        pwSuccessTimerRef.current = setTimeout(() => {
          setPwSuccess(null);
          pwSuccessTimerRef.current = null;
        }, 4000);
        return;
      }

      let data = {};
      try { data = await r.json(); } catch (_) { data = {}; }

      if (r.status === 401) {
        navigateTo('/login');
        return;
      }
      if (r.status === 429) {
        const sec = (data && data.retryAfter) || 60;
        setPwBanner(
          lang === 'zh'
            ? '请求过于频繁，请 ' + sec + ' 秒后再试'
            : 'Too many requests. Try again in ' + sec + ' seconds.'
        );
        return;
      }
      if (r.status === 400 && data && data.fields) {
        const mapped = {};
        Object.entries(data.fields).forEach(([k, code]) => { mapped[k] = pwErrMessage(code); });
        setPwErrors(mapped);
        setPwBanner(lang === 'zh' ? '请检查表单' : 'Please review the form');
        return;
      }
      setPwBanner(lang === 'zh' ? '操作失败，请稍后再试' : 'Failed. Please try again later');
    } catch (err) {
      setPwBanner(lang === 'zh' ? '网络错误，请检查连接' : 'Network error, please check your connection');
    } finally {
      setPwSubmitting(false);
    }
  };

  // Race guard: AuthProvider may still be loading when this mounts
  if (!user || !hydrated) {
    return (
      <div className="pb-scroll">
        <PBNav />
        <div className="pb-auth-shell">
          <div className="pb-auth-card" data-testid="profile-card">
            <div style={{ textAlign: 'center', padding: '24px 0', color: 'var(--pb-fg-muted)' }}>
              {lang === 'zh' ? '加载中…' : 'Loading…'}
            </div>
          </div>
        </div>
        <PBFooter />
      </div>
    );
  }

  const gradeKeys = ['senior1', 'senior2', 'senior3', 'college', 'graduated'];
  const gradeLabels = {
    senior1: lang === 'zh' ? '高一' : 'Senior 1 (Year 10)',
    senior2: lang === 'zh' ? '高二' : 'Senior 2 (Year 11)',
    senior3: lang === 'zh' ? '高三' : 'Senior 3 (Year 12)',
    college: lang === 'zh' ? '大学在读' : 'In college',
    graduated: lang === 'zh' ? '已毕业' : 'Graduated',
  };

  const typeLabels = {
    gaokao: lang === 'zh' ? '高考考生' : 'Gaokao student',
    abroad: lang === 'zh' ? '留学申请者' : 'Study-abroad applicant',
  };

  return (
    <div className="pb-scroll">
      <PBNav />
      <div className="pb-auth-shell">
        <div className="pb-auth-card" data-testid="profile-card">
          <div style={{ marginBottom: 12 }}><PBLogo size={36} /></div>
          <h1 className="pb-auth-title">
            {lang === 'zh' ? '我的资料' : 'Your profile'}
          </h1>
          <p className="pb-auth-sub">
            {lang === 'zh'
              ? '更新姓名、联系方式与目标方向'
              : 'Update your name, contact and target direction'}
          </p>

          {banner && (
            <div className="pb-auth-banner error" data-testid="profile-banner-error">{banner}</div>
          )}

          <form className="pb-auth-form" onSubmit={onSubmit} noValidate>

            {/* Email — read-only */}
            <div>
              <label className="pb-label" htmlFor="profile-email">
                {lang === 'zh' ? '邮箱' : 'Email'}
              </label>
              <div
                id="profile-email"
                className="pb-input"
                data-testid="profile-email"
                style={{
                  background: 'var(--pb-bg-muted, #f4f1ea)',
                  color: 'var(--pb-fg-muted)',
                  cursor: 'not-allowed',
                  userSelect: 'text',
                }}
                aria-readonly="true"
              >
                {user.email}
              </div>
            </div>

            {/* Name */}
            <div>
              <label className="pb-label" htmlFor="profile-name">
                {lang === 'zh' ? '姓名' : 'Name'}
              </label>
              <input
                id="profile-name"
                className="pb-input"
                type="text"
                autoComplete="name"
                value={form.name}
                onChange={setField('name')}
                data-testid="profile-name"
                required
              />
              {errors.name && (
                <div className="pb-auth-error" data-testid="profile-error-name">{errors.name}</div>
              )}
            </div>

            {/* Phone */}
            <div>
              <label className="pb-label" htmlFor="profile-phone">
                {lang === 'zh' ? '电话' : 'Phone'}{' '}
                <span style={{ fontWeight: 400, color: 'var(--pb-fg-muted)' }}>
                  {lang === 'zh' ? '(选填)' : '(optional)'}
                </span>
              </label>
              <input
                id="profile-phone"
                className="pb-input"
                type="tel"
                autoComplete="tel"
                value={form.phone}
                onChange={setField('phone')}
                data-testid="profile-phone"
              />
              {errors.phone && (
                <div className="pb-auth-error" data-testid="profile-error-phone">{errors.phone}</div>
              )}
            </div>

            {/* Student type radios */}
            <div>
              <div className="pb-label" style={{ marginBottom: 8 }}>
                {lang === 'zh' ? '学生类型' : 'Student type'}
              </div>
              <div className="pb-auth-radios">
                {['gaokao', 'abroad'].map((type) => (
                  <div
                    key={type}
                    className={'pb-auth-radio' + (form.studentType === type ? ' active' : '')}
                    onClick={() => setStudentType(type)}
                    data-testid={'profile-type-' + type}
                    role="radio"
                    aria-checked={form.studentType === type}
                    tabIndex={0}
                    onKeyDown={(e) => {
                      if (e.key === 'Enter' || e.key === ' ') {
                        e.preventDefault();
                        setStudentType(type);
                      }
                    }}
                  >
                    {typeLabels[type]}
                  </div>
                ))}
              </div>
              {errors.studentType && <div className="pb-auth-error">{errors.studentType}</div>}
            </div>

            {/* Grade select */}
            <div>
              <label className="pb-label" htmlFor="profile-grade">
                {lang === 'zh' ? '年级 / 阶段' : 'Grade / stage'}
              </label>
              <select
                id="profile-grade"
                className="pb-select"
                value={form.gradeYear}
                onChange={setField('gradeYear')}
                data-testid="profile-grade"
                required
              >
                <option value="" disabled>
                  {lang === 'zh' ? '请选择' : 'Please select'}
                </option>
                {gradeKeys.map((k) => (
                  <option key={k} value={k}>{gradeLabels[k]}</option>
                ))}
              </select>
              {errors.gradeYear && <div className="pb-auth-error">{errors.gradeYear}</div>}
            </div>

            <button
              type="submit"
              className="pb-btn pb-btn-primary"
              style={{ marginTop: 8, width: '100%' }}
              disabled={submitting}
              data-testid="profile-submit"
            >
              {submitting
                ? (lang === 'zh' ? '保存中…' : 'Saving…')
                : (lang === 'zh' ? '保存' : 'Save')}
            </button>

            {success && (
              <div
                className="pb-auth-banner success"
                data-testid="profile-success"
                style={{
                  marginTop: 12,
                  background: '#e7f5ec',
                  color: '#1f6b3a',
                  border: '1px solid #b8dcc6',
                  borderRadius: 8,
                  padding: '10px 12px',
                  fontSize: 14,
                }}
                role="status"
                aria-live="polite"
              >
                {success}
              </div>
            )}
          </form>
        </div>

        {/* Security card — change password (M1.4) */}
        <div className="pb-auth-card" data-testid="security-card" style={{ marginTop: 24 }}>
          <h2 className="pb-auth-title" style={{ fontSize: 22 }}>
            {lang === 'zh' ? '安全' : 'Security'}
          </h2>
          <p className="pb-auth-sub">
            {lang === 'zh' ? '更新登录密码,生效即时。' : 'Update your login password — takes effect immediately.'}
          </p>

          {pwBanner && (
            <div className="pb-auth-banner error" data-testid="security-banner-error">{pwBanner}</div>
          )}

          <form className="pb-auth-form" onSubmit={onChangePassword} noValidate>
            <div>
              <label className="pb-label" htmlFor="security-current">
                {lang === 'zh' ? '当前密码' : 'Current password'}
              </label>
              <input
                id="security-current"
                className="pb-input"
                type="password"
                autoComplete="current-password"
                value={pwForm.currentPassword}
                onChange={setPwField('currentPassword')}
                data-testid="security-current"
                required
              />
              {pwErrors.currentPassword && (
                <div className="pb-auth-error" data-testid="security-error-current">{pwErrors.currentPassword}</div>
              )}
            </div>

            <div>
              <label className="pb-label" htmlFor="security-new">
                {lang === 'zh' ? '新密码' : 'New password'}
              </label>
              <input
                id="security-new"
                className="pb-input"
                type="password"
                autoComplete="new-password"
                value={pwForm.newPassword}
                onChange={setPwField('newPassword')}
                data-testid="security-new"
                required
              />
              <div style={{ fontSize: 12, color: 'var(--pb-fg-muted)', marginTop: 4 }}>
                {lang === 'zh' ? '至少 8 位,包含字母与数字' : 'At least 8 chars, with letters and digits'}
              </div>
              {pwErrors.newPassword && (
                <div className="pb-auth-error" data-testid="security-error-new">{pwErrors.newPassword}</div>
              )}
            </div>

            <div>
              <label className="pb-label" htmlFor="security-confirm">
                {lang === 'zh' ? '确认新密码' : 'Confirm new password'}
              </label>
              <input
                id="security-confirm"
                className="pb-input"
                type="password"
                autoComplete="new-password"
                value={pwForm.confirmPassword}
                onChange={setPwField('confirmPassword')}
                data-testid="security-confirm"
                required
              />
              {pwErrors.confirmPassword && (
                <div className="pb-auth-error" data-testid="security-error-confirm">{pwErrors.confirmPassword}</div>
              )}
            </div>

            <button
              type="submit"
              className="pb-btn pb-btn-primary"
              style={{ marginTop: 8, width: '100%' }}
              disabled={pwSubmitting}
              data-testid="security-submit"
            >
              {pwSubmitting
                ? (lang === 'zh' ? '提交中…' : 'Submitting…')
                : (lang === 'zh' ? '更新密码' : 'Update password')}
            </button>

            {pwSuccess && (
              <div
                className="pb-auth-banner success"
                data-testid="security-success"
                style={{
                  marginTop: 12,
                  background: '#e7f5ec',
                  color: '#1f6b3a',
                  border: '1px solid #b8dcc6',
                  borderRadius: 8,
                  padding: '10px 12px',
                  fontSize: 14,
                }}
                role="status"
                aria-live="polite"
              >
                {pwSuccess}
              </div>
            )}
          </form>
        </div>
      </div>
      <PBFooter />
    </div>
  );
};

window.ProfilePage = ProfilePage;
