(function initFivaFieldIntentResolver(global) {
  "use strict";

  if (global.FIVA?.FieldIntentResolver) {
    if (typeof module !== "undefined" && module.exports) module.exports = global.FIVA.FieldIntentResolver;
    return;
  }

  const STANDARD_FIELDS = Object.freeze([
    "country",
    "mission",
    "nationality",
    "dateOfBirth",
    "email",
    "reEnterEmail",
    "expectedArrivalDate",
    "visaType",
    "purpose",
    "surname",
    "givenNames",
    "fullName",
    "gender",
    "passportNumber",
    "passportIssueDate",
    "passportExpiryDate"
  ]);

  const FIELD_INTENTS = Object.freeze({
    country: ["country", "applicationCountry", "applyingFrom", "applyingFromCountry", "applyingCountry", "visaCountry", "countryRegion", "country_region", "country/region you are applying visa from"],
    mission: ["mission", "indianMission", "indianMissionOffice", "missionOffice", "ivacCenter", "applicationCenter", "indian mission/office"],
    nationality: ["nationality", "citizenship", "countryOfCitizenship", "currentNationality", "nationalityRegion", "nationality/region", "nationalityByBirth"],
    dateOfBirth: ["dateOfBirth", "dob", "birthDate", "birth_date", "date of birth"],
    email: ["email", "emailId", "emailID", "email id", "emailAddress", "e-mail", "mail"],
    reEnterEmail: ["reEnterEmail", "confirmEmail", "re-enter email", "re enter email", "reEnterEmailId"],
    expectedArrivalDate: ["expectedArrivalDate", "expectedArrival", "arrivalDate", "dateOfArrival", "expected date of arrival", "expected date of journey", "dateOfJourney"],
    visaType: ["visaType", "visaService", "visa service", "typeOfVisa", "type of visa required", "visaCategory"],
    purpose: ["purpose", "purposeOfVisit", "visaPurpose", "visitPurpose"],
    surname: ["surname", "lastName", "familyName", "family_name"],
    givenNames: ["givenNames", "givenName", "given name", "given names", "firstName", "middleName"],
    fullName: ["fullName", "full name", "applicantName", "nameOfApplicant"],
    gender: ["gender", "sex"],
    passportNumber: ["passportNumber", "passportNo", "passport no", "passport number", "passNo", "pass_no"],
    passportIssueDate: ["passportIssueDate", "issueDate", "dateOfIssue", "date of issue"],
    passportExpiryDate: ["passportExpiryDate", "expiryDate", "dateOfExpiry", "date of expiry"]
  });

  const COUNTRY_ALIASES = Object.freeze({
    bangladesh: "BANGLADESH",
    bangladeshi: "BANGLADESH",
    bd: "BANGLADESH",
    bgd: "BANGLADESH",
    "p bgd": "BANGLADESH",
    india: "INDIA",
    indian: "INDIA",
    pakistan: "PAKISTAN",
    pakistani: "PAKISTAN",
    nepal: "NEPAL",
    nepalese: "NEPAL",
    "sri lanka": "SRI LANKA",
    "sri lankan": "SRI LANKA"
  });

  function compact(value = "") {
    return String(value || "")
      .normalize("NFKC")
      .replace(/[\u0000-\u001F\u007F-\u009F\u00A0\u200B-\u200F\uFEFF]/g, " ")
      .replace(/\s+/g, " ")
      .trim();
  }

  function normalize(value = "") {
    return compact(value)
      .toLowerCase()
      .replace(/&/g, " and ")
      .replace(/[_/-]+/g, " ")
      .replace(/[^a-z0-9@.]+/g, " ")
      .replace(/\s+/g, " ")
      .trim();
  }

  function normalizeKey(value = "") {
    return normalize(value).replace(/\s+/g, "");
  }

  function titleCase(value = "") {
    return compact(value)
      .toLowerCase()
      .replace(/\b[a-z]/g, (letter) => letter.toUpperCase());
  }

  function upperWords(value = "") {
    return compact(value)
      .replace(/[_]+/g, " ")
      .replace(/\s*-\s*/g, "-")
      .replace(/\s+/g, " ")
      .trim()
      .toUpperCase();
  }

  function sourceProfile(input = {}) {
    return input?.profile && typeof input.profile === "object" ? input.profile : input || {};
  }

  function lookupFor(input = {}) {
    const source = sourceProfile(input);
    const lookup = new Map();
    Object.entries(source || {}).forEach(([key, value]) => {
      if (String(key).startsWith("__")) return;
      lookup.set(String(key), value);
      lookup.set(normalizeKey(key), value);
    });
    return lookup;
  }

  function pickIntent(input = {}, fieldKey = "") {
    const lookup = lookupFor(input);
    const aliases = FIELD_INTENTS[fieldKey] || [fieldKey];
    for (const alias of aliases) {
      const direct = lookup.get(alias);
      if (compact(direct)) return { value: compact(direct), alias };
      const normalized = lookup.get(normalizeKey(alias));
      if (compact(normalized)) return { value: compact(normalized), alias };
    }
    return { value: "", alias: "" };
  }

  function normalizeCountry(value = "") {
    const alias = global.FIVA?.NormalizeOptionText?.nationalityAliasResolver?.(value);
    if (alias) return alias;
    const source = normalize(value);
    if (!source) return "";
    const exact = COUNTRY_ALIASES[source];
    if (exact) return exact;
    const fuzzy = Object.entries(COUNTRY_ALIASES).find(([key]) => source.includes(key) || key.includes(source));
    return fuzzy?.[1] || upperWords(value);
  }

  function normalizeMission(value = "", country = "") {
    const source = normalize(value);
    if (!source) return "";
    if (/dhaka/.test(source) && (/bangladesh|mission|office|dhaka/.test(source) || country === "BANGLADESH")) return "BANGLADESH-DHAKA";
    if (source === "dhaka" && country === "BANGLADESH") return "BANGLADESH-DHAKA";
    return upperWords(value).replace(/^BANGLADESH DHAKA$/, "BANGLADESH-DHAKA");
  }

  function normalizeVisaType(value = "") {
    const source = normalize(value);
    if (!source) return "";
    if (/tourist|tourism|travel/.test(source)) return "e-Tourist Visa";
    if (/business/.test(source)) return "e-Business Visa";
    if (/medical attendant/.test(source)) return "Medical Attendant Visa";
    if (/medical/.test(source)) return "Medical Visa";
    if (/student|study/.test(source)) return "Student Visa";
    if (/entry/.test(source)) return "Entry Visa";
    return compact(value);
  }

  function normalizePurpose(value = "") {
    const source = normalize(value);
    if (!source) return "";
    if (/business/.test(source)) return "Business";
    if (/medical attendant/.test(source)) return "Medical Attendant";
    if (/medical/.test(source)) return "Medical Treatment";
    if (/touris|travel|sightseeing|visit/.test(source)) return "Tourism";
    if (/student|study/.test(source)) return "Study";
    return titleCase(value);
  }

  function normalizeGender(value = "") {
    const source = normalize(value);
    if (source === "f" || /\bfemale\b/.test(source)) return "Female";
    if (source === "m" || /\bmale\b/.test(source)) return "Male";
    return "";
  }

  function normalizeDate(value = "") {
    return global.FIVA?.StrictDobValidator?.normalizeDate?.(value) || "";
  }

  function normalizeEmail(value = "") {
    return compact(value).match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i)?.[0]?.toLowerCase() || "";
  }

  function normalizePassport(value = "") {
    const passport = compact(value).toUpperCase().replace(/[^A-Z0-9]/g, "");
    return /^[A-Z0-9]{6,16}$/.test(passport) ? passport : "";
  }

  function defaultCountryFor(options = {}, hasData = false) {
    const site = String(options.siteUrl || "").toLowerCase();
    return hasData && options.allowDefaultCountry === true && /indianvisa-bangladesh\.nic\.in/.test(site)
      ? "BANGLADESH"
      : "";
  }

  function resolveField(input = {}, fieldKey = "", options = {}) {
    const source = sourceProfile(input);
    const hasData = Object.entries(source).some(([key, value]) => !String(key).startsWith("__") && compact(value));
    const picked = pickIntent(source, fieldKey);
    let value = picked.value;

    if (fieldKey === "country") value = normalizeCountry(value) || defaultCountryFor(options, hasData);
    else if (fieldKey === "mission") {
      const country = normalizeCountry(pickIntent(source, "country").value) || defaultCountryFor(options, hasData);
      value = normalizeMission(value, country) || (country === "BANGLADESH" ? "BANGLADESH-DHAKA" : "");
    } else if (fieldKey === "nationality") value = normalizeCountry(value);
    else if (fieldKey === "dateOfBirth" || fieldKey === "expectedArrivalDate" || fieldKey === "passportIssueDate" || fieldKey === "passportExpiryDate") value = normalizeDate(value);
    else if (fieldKey === "email" || fieldKey === "reEnterEmail") value = normalizeEmail(value);
    else if (fieldKey === "visaType") value = normalizeVisaType(value);
    else if (fieldKey === "purpose") value = normalizePurpose(value);
    else if (fieldKey === "gender") value = normalizeGender(value);
    else if (fieldKey === "passportNumber") value = normalizePassport(value);
    else if (["surname", "givenNames", "fullName"].includes(fieldKey)) value = compact(value);
    else value = compact(value);

    return {
      field: fieldKey,
      value,
      alias: picked.alias,
      present: Boolean(value),
      source: picked.alias ? "document" : value && (fieldKey === "country" || fieldKey === "mission") ? "site_context" : "missing",
      reason: value ? "" : "parser_missing_field"
    };
  }

  function splitFullName(profile = {}) {
    const fullName = compact(profile.fullName);
    if (!fullName || (profile.givenNames && profile.surname)) return profile;
    const parts = fullName.split(" ").filter(Boolean);
    if (parts.length < 2) return { ...profile, givenNames: profile.givenNames || fullName };
    return {
      ...profile,
      givenNames: profile.givenNames || parts.slice(0, -1).join(" "),
      surname: profile.surname || parts.slice(-1).join("")
    };
  }

  function resolveProfile(input = {}, options = {}) {
    const profile = {};
    const meta = {};
    STANDARD_FIELDS.forEach((fieldKey) => {
      const resolved = resolveField(input, fieldKey, options);
      if (!resolved.value) return;
      profile[fieldKey] = resolved.value;
      meta[fieldKey] = {
        source: resolved.source,
        alias: resolved.alias,
        verified: resolved.source === "document",
        confidence: resolved.source === "document" ? 94 : 82
      };
    });

    if (profile.email && !profile.reEnterEmail) {
      profile.reEnterEmail = profile.email;
      meta.reEnterEmail = { source: "document", alias: "email", verified: true, confidence: 94 };
    }
    if (profile.dateOfBirth && !profile.dob) profile.dob = profile.dateOfBirth;
    if (profile.expectedArrivalDate && !profile.arrivalDate) profile.arrivalDate = profile.expectedArrivalDate;
    if (profile.givenNames && !profile.givenName) profile.givenName = profile.givenNames;

    const withName = splitFullName(profile);
    return {
      profile: withName,
      meta,
      missing: STANDARD_FIELDS.filter((fieldKey) => !withName[fieldKey])
    };
  }

  function fieldValueFor(input = {}, fieldKey = "", options = {}) {
    return resolveField(input, fieldKey, options).value;
  }

  const FieldIntentResolver = Object.freeze({
    FIELD_INTENTS,
    STANDARD_FIELDS,
    compact,
    fieldValueFor,
    normalize,
    normalizeCountry,
    normalizeDate,
    normalizeEmail,
    normalizeMission,
    normalizePurpose,
    normalizeVisaType,
    pickIntent,
    resolveField,
    resolveProfile
  });

  global.FIVA = Object.assign(global.FIVA || {}, { FieldIntentResolver });

  if (typeof module !== "undefined" && module.exports) {
    module.exports = FieldIntentResolver;
  }
})(typeof globalThis !== "undefined" ? globalThis : this);
