/* YeYe Expat Portal — v15 full-form profile wizard */

const YEYE_WIZARD_SECTION_ORDER = [
  'contact',
  'personal',
  'employer',
  'employerPrev',
  'addrResidence',
  'addrCzechia',
  'addrShipping',
  'passport',
];

function wizardTemplate(copy, values) {
  return Object.entries(values || {}).reduce(
    (result, [key, value]) => result.replaceAll('{' + key + '}', value),
    String(copy || '')
  );
}

function wizardFieldLabelKey(key) {
  return 'wizard.field.' + String(key || '');
}

function wizardOptionLabel(value, t) {
  const normalized = String(value || '').trim().toLowerCase();
  const optionKey = 'wizard.option.' + normalized;
  const translated = t(optionKey);
  if (translated !== optionKey) return translated;
  const maritalKey = 'wizard.marital.' + normalized;
  const marital = t(maritalKey);
  return marital !== maritalKey ? marital : value;
}

function buildWizardValues(contact, entries) {
  return entries.reduce((values, entry) => {
    const raw = window.YEYE_PROFILE && window.YEYE_PROFILE.getValue
      ? window.YEYE_PROFILE.getValue(contact || {}, entry)
      : (contact && contact[entry.key]);
    values[entry.key] = raw == null ? '' : String(raw);
    return values;
  }, {});
}

function customFieldIdFromContact(contact, entry) {
  if (entry && entry.ghlFieldId) return entry.ghlFieldId;
  const shortKey = String(entry && entry.key || '').replace(/^contact\./, '').toLowerCase();
  const raw = (contact && contact.raw) || contact || {};
  const fields = (contact && contact.customFields) || raw.customFields || [];
  if (!Array.isArray(fields)) return '';
  const match = fields.find((field) => {
    const key = String(field && (field.key || field.fieldKey || field.name) || '').replace(/^contact\./, '').toLowerCase();
    return key === shortKey;
  });
  return match ? String(match.id || match.fieldId || match.customFieldId || '') : '';
}

async function saveWizardProfile(contact, answers, entries) {
  const contactId = contact && (contact.contactId || contact.id);
  const emailAddr = (contact && contact.email) || '';
  if (!contactId || !emailAddr) throw new Error('missing-contact');

  const fieldEntries = entries || (window.YEYE_REQUIRED_FIELDS || []).filter((entry) => (
    Object.prototype.hasOwnProperty.call(answers || {}, entry.key)
  ));
  const basic = {};
  const customs = [];
  fieldEntries.forEach((entry) => {
    if (!Object.prototype.hasOwnProperty.call(answers || {}, entry.key)) return;
    const value = answers[entry.key] == null ? '' : String(answers[entry.key]);
    if (!String(entry.key || '').startsWith('contact.')) {
      basic[entry.key] = value;
      return;
    }
    const customId = customFieldIdFromContact(contact, entry);
    if (!customId) throw new Error('missing-custom-field-id:' + entry.key);
    customs.push({
      id: customId,
      ghlFieldId: customId,
      key: String(entry.key),
      value,
    });
  });

  if (!window.YEYE_BACKEND || !window.YEYE_BACKEND.updateContactProfile) {
    throw new Error('write-backend-not-configured');
  }
  await window.YEYE_BACKEND.updateContactProfile({ contactId, basic, customFields: customs });
  return {
    updates: basic,
    customFieldUpdates: customs.map((field) => ({
      id: field.id,
      key: field.key,
      value: field.value,
    })),
  };
}

const YEYE_WIZARD_COPY_MAPS = {
  residenceToCzechia: {
    'contact.municipality_in_czechia': 'contact.municipality_in_residence',
    'contact.district_in_czechia': 'contact.district',
    'contact.street_number_in_czechia': 'contact.street_number',
    'contact.building_number_in_czechia': 'contact.building_no',
    'contact.postalzip_code_in_czechia': 'contact.zip_code',
  },
  residenceToShipping: {
    'contact.delivery_country_country_list': 'contact.country_residence_country_list',
    'contact.delivery_municipality': 'contact.municipality_in_residence',
    'contact.delivery_municipal_district': 'contact.district',
    'contact.delivery_street': 'contact.street_number',
    'contact.delivery_building_number': 'contact.building_no',
    'contact.delivery_post_code': 'contact.zip_code',
  },
  czechiaToShipping: {
    'contact.delivery_country_country_list': null,
    'contact.delivery_municipality': 'contact.municipality_in_czechia',
    'contact.delivery_municipal_district': 'contact.district_in_czechia',
    'contact.delivery_street': 'contact.street_number_in_czechia',
    'contact.delivery_building_number': 'contact.building_number_in_czechia',
    'contact.delivery_post_code': 'contact.postalzip_code_in_czechia',
  },
};

function residenceIsCzechia(answers) {
  const raw = String((answers && answers['contact.country_residence_country_list']) || '').toLowerCase();
  return /czech|česk|cesk|^cz$/.test(raw);
}

function BranchQuestion({ label, value, onChange, yesLabel, noLabel, error }) {
  const pick = (v) => (e) => { e && e.preventDefault && e.preventDefault(); onChange(v); };
  return (
    <div className={'wizard-branch ' + (error ? 'is-error' : '')}>
      <div className="wizard-branch-q">{label}</div>
      <div className="wizard-branch-actions">
        <button type="button" className={'wizard-branch-btn ' + (value === 'yes' ? 'is-on' : '')} onClick={pick('yes')}>
          <Icon name="check" size={15} /> {yesLabel}
        </button>
        <button type="button" className={'wizard-branch-btn ' + (value === 'no' ? 'is-on' : '')} onClick={pick('no')}>
          <Icon name="x" size={15} /> {noLabel}
        </button>
      </div>
    </div>
  );
}

function ProfileWizard({ contact, onClose, onSaved, initialSection = null }) {
  const { t, lang } = useT();
  const entries = React.useMemo(() => window.YEYE_REQUIRED_FIELDS || [], []);
  const initialValues = React.useMemo(() => buildWizardValues(contact, entries), [contact, entries]);
  const [answers, setAnswers] = React.useState(initialValues);
  const [saving, setSaving] = React.useState(false);
  const [error, setError] = React.useState('');
  const [branch, setBranch] = React.useState({
    residenceSameAsCzechia: '',
    residenceSameAsShipping: '',
    czechiaSameAsShipping: '',
  });
  const [branchError, setBranchError] = React.useState('');
  const contactReady = !!(contact && (contact.contactId || contact.id) && contact.email);
  const isFilled = (value) => window.YEYE_PROFILE && window.YEYE_PROFILE.isFilled
    ? window.YEYE_PROFILE.isFilled(value)
    : String(value || '').trim().length > 0;

  const sections = React.useMemo(() => YEYE_WIZARD_SECTION_ORDER.map((sectionKey) => ({
    key: sectionKey,
    fields: entries.filter((entry) => entry.section === sectionKey),
  })).filter((section) => section.fields.length), [entries]);

  const activeSteps = React.useMemo(() => sections.filter((section) => {
    if (section.key === 'addrCzechia' && branch.residenceSameAsCzechia === 'yes') return false;
    if (section.key === 'addrShipping'
      && (branch.residenceSameAsShipping === 'yes' || branch.czechiaSameAsShipping === 'yes')) return false;
    return true;
  }), [sections, branch]);

  const initialStepIndex = React.useMemo(() => {
    if (!initialSection) return 0;
    const idx = activeSteps.findIndex((s) => s.key === initialSection);
    return idx >= 0 ? idx : 0;
  }, [initialSection, activeSteps]);
  const [stepIndex, setStepIndex] = React.useState(initialStepIndex);

  React.useEffect(() => {
    if (stepIndex > activeSteps.length - 1) {
      setStepIndex(Math.max(0, activeSteps.length - 1));
    }
  }, [stepIndex, activeSteps.length]);

  const currentSection = activeSteps[Math.min(stepIndex, activeSteps.length - 1)] || null;
  const isLastStep = stepIndex >= activeSteps.length - 1;

  const changedEntries = entries.filter((entry) => (
    String(answers[entry.key] == null ? '' : answers[entry.key])
      !== String(initialValues[entry.key] == null ? '' : initialValues[entry.key])
  ));
  const hasChanges = changedEntries.length > 0;

  const closeWizard = () => { if (onClose) onClose(); };

  const applyCopyMap = (map) => {
    setAnswers((previous) => {
      const next = { ...previous };
      Object.entries(map).forEach(([target, source]) => {
        if (source == null) return;
        next[target] = previous[source] || '';
      });
      return next;
    });
  };

  const setBranchAnswer = (key, value) => {
    setBranchError('');
    setError('');
    setBranch((prev) => ({ ...prev, [key]: value }));
    if (value !== 'yes') return;
    if (key === 'residenceSameAsCzechia') applyCopyMap(YEYE_WIZARD_COPY_MAPS.residenceToCzechia);
    if (key === 'residenceSameAsShipping') applyCopyMap(YEYE_WIZARD_COPY_MAPS.residenceToShipping);
    if (key === 'czechiaSameAsShipping') applyCopyMap(YEYE_WIZARD_COPY_MAPS.czechiaToShipping);
  };

  const branchQuestionsForCurrent = React.useMemo(() => {
    if (!currentSection) return [];
    const list = [];
    if (currentSection.key === 'addrResidence') {
      if (residenceIsCzechia(answers)) {
        list.push({ key: 'residenceSameAsCzechia', label: t('wizard.branch.residenceSameAsCzechia') });
      }
      list.push({ key: 'residenceSameAsShipping', label: t('wizard.branch.residenceSameAsShipping') });
    }
    if (currentSection.key === 'addrCzechia' && branch.residenceSameAsShipping !== 'yes') {
      list.push({ key: 'czechiaSameAsShipping', label: t('wizard.branch.czechiaSameAsShipping') });
    }
    return list;
  }, [currentSection, answers, branch.residenceSameAsShipping, t]);

  const validateBranches = () => branchQuestionsForCurrent.every((q) => branch[q.key] === 'yes' || branch[q.key] === 'no');

  const save = async ({ finish = false } = {}) => {
    if (!contactReady) {
      setError(t('wizard.missingContact'));
      return false;
    }
    if (!hasChanges) {
      if (finish) closeWizard();
      return true;
    }
    const missingAfterSave = window.YEYE_PROFILE && window.YEYE_PROFILE.missing
      ? window.YEYE_PROFILE.missing(contact || {}, answers)
      : [];
    setSaving(true);
    setError('');
    const changedAnswers = changedEntries.reduce((values, entry) => {
      values[entry.key] = answers[entry.key];
      return values;
    }, {});
    try {
      const optimisticPatch = await saveWizardProfile(contact, changedAnswers, changedEntries);
      if (window.YEYE_WELCOME && window.YEYE_WELCOME.markShown) window.YEYE_WELCOME.markShown();
      window.YEYE_TOAST && window.YEYE_TOAST(t('wizard.savedToast'));
      if (missingAfterSave.length) {
        window.YEYE_TOAST && window.YEYE_TOAST(
          t('profileFields.missingBanner').replace('{count}', missingAfterSave.length)
        );
      }
      const contactId = contact && (contact.contactId || contact.id);
      if (contactId && window.YEYE_CONTACT_STATE && window.YEYE_CONTACT_STATE.applyOptimisticUpdate) {
        window.YEYE_CONTACT_STATE.applyOptimisticUpdate(contactId, optimisticPatch);
      }
      if (onSaved) onSaved(optimisticPatch);
      if (finish) closeWizard();
      return true;
    } catch (err) {
      console.warn('Profile wizard save failed', err);
      setError(t('wizard.saveFailed'));
      return false;
    } finally {
      setSaving(false);
    }
  };

  const goNext = async () => {
    if (!validateBranches()) {
      setBranchError(t('wizard.branch.required'));
      return;
    }
    setBranchError('');
    if (isLastStep) {
      await save({ finish: true });
      return;
    }
    setStepIndex((idx) => Math.min(idx + 1, activeSteps.length - 1));
  };
  const goBack = () => {
    setBranchError('');
    setStepIndex((idx) => Math.max(idx - 1, 0));
  };

  const stepTotal = activeSteps.length;
  const stepCurrent = Math.min(stepIndex + 1, stepTotal);
  const percent = stepTotal ? Math.round((stepCurrent / stepTotal) * 100) : 100;

  const footer = (
    <div className="wizard-footer-content">
      {(error || branchError) && (
        <div className="wizard-inline-error" role="alert">
          <Icon name="triangle-alert" size={16} />
          <span>{error || branchError}</span>
        </div>
      )}
      <div className="wizard-footer-actions">
        <Btn variant="ghost" disabled={saving || stepIndex === 0} onClick={goBack} icon="arrow-left">
          {t('wizard.back')}
        </Btn>
        <Btn
          variant="primary"
          iconR={isLastStep ? 'check' : 'arrow-right'}
          disabled={saving || !contactReady}
          onClick={goNext}
        >
          {saving ? t('c.saving') : (isLastStep ? t('wizard.saveAndFinish') : t('wizard.next'))}
        </Btn>
      </div>
    </div>
  );

  const renderSection = (section) => {
    const sectionFilled = section.fields.filter((entry) => isFilled(answers[entry.key])).length;
    const captions = (window.YEYE_REQUIRED_SECTIONS && window.YEYE_REQUIRED_SECTIONS[section.key]) || {};
    const sectionLabel = captions[lang] || captions.en || section.key;
    return (
      <section className="wizard-form-section" key={section.key}>
        <header className="wizard-section-header">
          <div><Icon name="map-pin" size={16} /><h4>{sectionLabel}</h4></div>
          <span>{wizardTemplate(t('wizard.sectionCount'), { filled: sectionFilled, total: section.fields.length })}</span>
        </header>
        <div className="wizard-section-fields">
          {section.fields.map((entry) => {
            const kind = (window.YEYE_PROFILE && window.YEYE_PROFILE.kindFor(entry.key)) || entry.kind || 'text';
            const baseOptions = (window.YEYE_PROFILE && window.YEYE_PROFILE.optionsFor(entry.key)) || entry.options || null;
            const options = baseOptions && baseOptions.map((option) => ({
              value: option,
              label: wizardOptionLabel(option, t),
            }));
            const labelKey = wizardFieldLabelKey(entry.key);
            const label = t(labelKey);
            return (
              <label className="wizard-field" key={entry.key}>
                <span>{label}</span>
                {window.renderProfileFieldWidget({
                  kind,
                  value: answers[entry.key],
                  onChange: (value) => {
                    setError('');
                    setAnswers((previous) => ({ ...previous, [entry.key]: value }));
                  },
                  options,
                  label,
                  lang,
                  placeholder: kind === 'select' || kind === 'country' ? t('wizard.selectPlaceholder') : label,
                  className: 'wizard-field-control',
                })}
              </label>
            );
          })}
        </div>
      </section>
    );
  };

  return (
    <Modal wide icon="clipboard-list" title={t('wizard.title')} onClose={closeWizard} footer={footer}>
      <div className="wizard-form">
        <div className="wizard-progress-block">
          <div className="wizard-progress-copy">
            <span>{t('wizard.progressTitle')}</span>
            <strong>
              {wizardTemplate(t('wizard.stepIndicator'), { current: stepCurrent, total: stepTotal })} · {percent}%
            </strong>
          </div>
          <div className="wizard-progress-track" aria-valuemin="0" aria-valuemax="100" aria-valuenow={percent} role="progressbar">
            <span style={{ width: percent + '%' }} />
          </div>
        </div>

        {currentSection && renderSection(currentSection)}

        {branchQuestionsForCurrent.length > 0 && (
          <div className="wizard-branch-block">
            {branchQuestionsForCurrent.map((q) => (
              <BranchQuestion
                key={q.key}
                label={q.label}
                value={branch[q.key]}
                onChange={(v) => setBranchAnswer(q.key, v)}
                yesLabel={t('wizard.branch.yes')}
                noLabel={t('wizard.branch.no')}
                error={!!branchError && !(branch[q.key] === 'yes' || branch[q.key] === 'no')}
              />
            ))}
          </div>
        )}

        <div className="wizard-filled-hint">
          <Icon name="lightbulb" size={17} />
          <span>{t('wizard.filledHint')}</span>
        </div>
        {!contactReady && (
          <div className="wizard-inline-error" role="alert">
            <Icon name="triangle-alert" size={16} />
            <span>{t('wizard.missingContact')}</span>
          </div>
        )}
      </div>
    </Modal>
  );
}

Object.assign(window, { ProfileWizard, saveWizardProfile });
