$(document).ready(function () {
  const $form = $("#form-with-validation-submit");
  const cityList = [
    "Roma",
    "Milano",
    "Torino",
    "Napoli",
    "Bologna",
    "Firenze",
    "Genova",
    "Cagliari",
    "Udine",
    "Caserta",
  ];
  const licenseTypes = ["A1", "A", "B", "C", "D"];
  const radioOptions = [
    "Celibe/Nubile",
    "Sposato/a",
    "Divorziato/a",
    "Vedovo/a",
  ];
  const checkboxDocs = [
    "Carta d'identità",
    "Patente",
    "Passaporto",
    "Tessera sanitaria",
  ];

  // ========== Render dynamic options ==========

  function renderOptions(id, items, renderFn) {
    items.forEach((item, index) => {
      $form.find("#" + id).append(renderFn(item, index));
    });
  }

  renderOptions("cityList", cityList, function (c) {
    return `<div class="option" tabindex="0" value="${c}">${c}</div>`;
  });

  renderOptions("licenseTypes", licenseTypes, function (l, i) {
    return `
        <li class="option-item">
          <div class="inail-checkbox">
            <input type="checkbox" id="license-${i}" class="custom-checkbox option-checkbox" value="${l}" aria-label="${l}">
            <label for="license-${i}">
              <span class="custom-checkbox-background mr-2">
                <i class="fa inail-checkbox-icon"></i>
              </span>
              <span>${l}</span>
            </label>
          </div>
        </li>`;
  });

  renderOptions("statoContainer", radioOptions, function (o, i) {
    return `
        <div class="col-lg-3 col-md-3 col-sm-6 col-xs-12 p-0">
          <label class="inail-radio-button" for="stato_civile_${i}">
            <input type="radio" name="statoCivile" class="inail-radio-input" id="stato_civile_${i}" value="${o}" checked>
            <div class="inail-radio-background">
              <div class="inail-radio-inner-circle"></div>
            </div>
            ${o}
          </label>
        </div>`;
  });

  renderOptions("documentsContainer", checkboxDocs, function (d) {
    return `
        <div class="col-lg-3 col-md-3 col-sm-6 col-xs-12 px-0 py-2">
          <input type="checkbox" name="documents" id="${d}" class="custom-checkbox option-checkbox" aria-labelledby="label-${d}" value="${d}">
          <label id="label-${d}" for="${d}">
            <span class="custom-checkbox-background">
              <i class="fa inail-checkbox-icon"></i>
            </span>
            <span>${d}</span>
          </label>
        </div>`;
  });

  // ========== Error Helpers ==========

  var labels = {
    nome: "Nome",
    surname: "Cognome",
    email: "Email",
    gender: "Sesso",
    birthday: "Data di nascita",
    phone: "Telefono",
    city: "Città",
    address: "Indirizzo",
    cap: "CAP",
    biografia: "Biografia",
    dateFrom: "Dal",
    dateTo: "Al",
    numberFrom: "Da",
    numberTo: "A",
    patenti: "Patenti",
    statoCivile: "Stato civile",
    documents: "Documenti allegati",
    employer: "Ultima occupazione",
  };

  function getError(field, type) {
    if (type === "required")
      return "Errore " + labels[field] + ": Campo obbligatorio.";
    if (type === "email") return "Indirizzo email non valido.";
    if (type === "minLength")
      return "Errore " + labels[field] + ": Minimo 2 elementi richiesti.";
    if (type === "rangeDate")
      return "La data di inizio deve precedere la fine.";
    if (type === "nan")
      return "Errore " + labels[field] + " deve essere un numero.";
    if (type === "rangeNum")
      return "Errore Intervallo numerico: Intervallo non corretto";
    if (type === "dateFormat") return "Formato data non valido (gg/mm/aaaa)";
    return "";
  }

  var labelsFeedback = {
    nome: "Nome",
    surname: "Cognome",
    email: "Email",
    gender: "Sesso",
    birthday: "Data di nascita",
    phone: "Telefono",
    city: "Città",
    address: "Indirizzo",
    cap: "CAP",
    biografia: "Biografia",
    dateFrom: "Periodo - Dal",
    dateTo: "Periodo - Al",
    numberFrom: "Da (numero)",
    numberTo: "A (numero)",
    patenti: "Patenti",
    statoCivile: "Stato civile",
    documents: "Documenti allegati",
    employer: "Ultima occupazione",
    rangeNum: "Intervallo numerico da-a",
    civilStatus: "Stato civile",
  };

  function getErrorFeedback(field, type) {
    var label = labelsFeedback[field] || field;

    switch (type) {
      case "required":
        return " Campo obbligatorio";
      case "email":
        return "Indirizzo email non valido";
      case "minLength":
        return " Seleziona almeno 2 elementi";
      case "rangeDate":
        return " La data di ritorno deve essere successiva alla partenza";
      case "nan":
        return " deve essere un numero";
      case "rangeNum":
        return " Intervallo non corretto";
      case "dateFormat":
        return " Formato data non valido (gg/mm/aaaa)";
      default:
        return " Errore non definito";
    }
  }

  function showErr(field, msg, announceError = true) {
    var $input = $form.find("#" + field);
    var $errorDiv = $form.find("#error-" + field);
    var isError = !!msg;

    $input
      .toggleClass("inail-input-error", isError)
      .attr("aria-invalid", isError);

    if (field === "city") {
      $errorDiv.html(
        isError
          ? '<span class="inail-span-error"><i class="fa-solid fa-circle-exclamation"></i> ' +
              msg +
              "</span>"
          : '<span id="comboHint" class="inail-span-ht inail-span-ht-combobox">Selezionare la città</span>'
      );
    } else {
      $errorDiv.html(
        isError
          ? '<span class="inail-span-error"><i class="fa-solid fa-circle-exclamation"></i> ' +
              msg +
              "</span>"
          : ""
      );
    }

    if (isError && announceError) {
      $("#errorAnnouncer").remove();

      // Crea e appende nuovo div nascosto
      $("<div>", {
        id: "errorAnnouncer",
        role: "alert",
        "aria-live": "assertive",
        text: msg,
        class: "sr-only",
      }).appendTo("body");

      setTimeout(() => {
        $("#errorAnnouncer").remove();
      }, 500);
    }
  }

  function showGroupError(msg, groupSelector, errorSelector) {
    var isError = !!msg;
    $form.find(groupSelector).toggleClass("inail-radio-group-error", isError);
    $form
      .find(errorSelector)
      .html(
        isError
          ? '<span class="inail-span-error"><i class="fa-solid fa-circle-exclamation"></i> ' +
              msg +
              "</span>"
          : ""
      );
  }

  // ========== Validation Functions ==========

  function validateField(f) {
    const $el = $form.find("#" + f);
    const val = $el.val()?.toString().trim() || "";
    let msg = "";

    if ($el.is("select")) {
      if (val === "") {
        msg = getError(f, "required");
      }
    } else if ($el.is(":radio") || $el.is(":checkbox")) {
      const name = $el.attr("name");
      const isChecked = $(`[name="${name}"]:checked`).length > 0;
      if (!isChecked) {
        msg = getError(f, "required");
      }
    } else {
      if (!val) {
        msg = getError(f, "required");
      } else if (f === "email" && !/^\S+@\S+\.\S+$/.test(val)) {
        msg = getError(f, "email");
      }
    }

    showErr(f, msg, false);
    return !msg;
  }

  function validateMulti(
    field,
    checkboxContainerId,
    announceError = true,
    min = 2,
    currentErrorText
  ) {
    const selected = $form.find(
      `#${checkboxContainerId} input[type=checkbox]:checked`
    ).length;

    let isValid = true;
    const errors = {};

    if (selected === 0) {
      if (currentErrorText !== getError(field, "required").trim()) {
        showErr(field, getError(field, "required"), announceError);
        errors[field] = "required";
        isValid = false;
      }
    } else if (selected < min) {
      if (currentErrorText !== getError(field, "minLength").trim()) {
        showErr(field, getError(field, "minLength"), announceError);
        errors[field] = "minLength";
        isValid = false;
      }
    } else {
      showErr(field, "", false);
    }

    return { isValid, errors };
  }

  function validateRadio() {
    const selected = $form.find('input[name="statoCivile"]:checked').length;
    const msg = selected === 0 ? getError("statoCivile", "required") : "";
    showGroupError(msg, "#civilStatus", "#error-civilStatus");
    return !msg;
  }

  function validateCheckbox(announceError = true, currentErrorText) {
    const selected = $form.find('input[name="documents"]:checked').length;

    const field = "documents";
    const containerSelector = "#documentsContainer";
    const errorSelector = "#error-documents";

    let msg = "";
    let isValid = true;
    const errors = {};

    if (selected === 0) {
      msg = getError(field, "required");
      errors[field] = "required";
      isValid = false;
      if (currentErrorText !== msg.trim() && announceError) {
        // Crea e appende nuovo div nascosto
        $("<div>", {
          id: "errorAnnouncer",
          role: "alert",
          "aria-live": "assertive",
          text: "Errore Documenti allegati: Campo obbligatorio.",
          class: "sr-only",
        }).appendTo("body");

        setTimeout(() => {
          $("#errorAnnouncer").remove();
        }, 500);
      }
    } else if (selected < 2) {
      msg = getError(field, "minLength");
      errors[field] = "minLength";
      isValid = false;
      if (currentErrorText !== msg.trim() && announceError) {
        $("#errorAnnouncer").remove();

        // Crea e appende nuovo div nascosto
        $("<div>", {
          id: "errorAnnouncer",
          role: "alert",
          "aria-live": "assertive",
          text: "Errore Documenti allegati: Minimo 2 elementi richiesti.",
          class: "sr-only",
        }).appendTo("body");

        setTimeout(() => {
          $("#errorAnnouncer").remove();
        }, 500);
      }
    }

    showGroupError(msg, containerSelector, errorSelector);

    $form.find(`${containerSelector} input[type=checkbox]`).each(function () {
      if (msg) {
        $(this).addClass("custom-checkbox-error");
      } else {
        $(this).removeClass("custom-checkbox-error");
      }
    });

    return { isValid, errors };
  }

  const touchedDateRange = {
    touchedDateFrom: false,
    touchedDateTo: false,
  };
  function parseDate(value) {
    const match = /^(\d{2})\/(\d{2})\/(\d{4})$/.exec(value);
    if (!match) return null;
    const [_, dd, mm, yyyy] = match.map(Number);
    const date = new Date(yyyy, mm - 1, dd);
    return date.getDate() === dd && date.getMonth() === mm - 1 ? date : null;
  }

  function validateDates() {
    const valFrom = $form.find("#dateFrom").val()?.toString().trim() || "";
    const valTo = $form.find("#dateTo").val()?.toString().trim() || "";

    const dateFrom = parseDate(valFrom);
    const dateTo = parseDate(valTo);

    let isValid = true;
    const errors = {};

    // Validate dateFrom
    if (!valFrom) {
      if (touchedDateRange.touchedDateFrom)
        showErr("dateFrom", getError("dateFrom", "required"), false);
      errors["dateFrom"] = "required";
      isValid = false;
    } else if (!dateFrom) {
      if (touchedDateRange.touchedDateFrom)
        showErr("dateFrom", getError("dateFrom", "dateFormat"), false);
      errors["dateFrom"] = "dateFormat";
      isValid = false;
    } else {
      showErr("dateFrom", "");
    }

    // Validate dateTo
    if (!valTo) {
      if (touchedDateRange.touchedDateTo)
        showErr("dateTo", getError("dateTo", "required"), false);
      errors["dateTo"] = "required";
      isValid = false;
    } else if (!dateTo) {
      if (touchedDateRange.touchedDateTo)
        showErr("dateTo", getError("dateTo", "dateFormat"), false);
      errors["dateTo"] = "dateFormat";
      isValid = false;
    } else if (
      dateFrom &&
      touchedDateRange.touchedDateFrom &&
      touchedDateRange.touchedDateTo &&
      dateTo <= dateFrom
    ) {
      showErr("dateTo", getError("dateTo", "rangeDate"), false);
      errors["dateTo"] = "rangeDate";
      isValid = false;
    } else {
      showErr("dateTo", "");
    }

    return { isValid, errors };
  }

  const touched = {
    numberFrom: false,
    numberTo: false,
  };

  function isValidNumber(val) {
    return /^-?\d+(\.\d+)?([eE][-+]?\d+)?$/.test(val.trim());
  }

  function clearRangeErrors() {
    $form.find("#error-range").hide().empty();
    showErr("numberFrom", "");
    showErr("numberTo", "");
  }

  function validateNumbers() {
    const val1 = $form.find("#numberFrom").val()?.toString().trim() || "";
    const val2 = $form.find("#numberTo").val()?.toString().trim() || "";

    const numFrom = parseFloat(val1);
    const numTo = parseFloat(val2);

    const validFrom = isValidNumber(val1);
    const validTo = isValidNumber(val2);

    let isValid = true;
    const errors = {};

    clearRangeErrors();

    // Validate numberFrom
    if (!val1) {
      if (touched.numberFrom)
        showErr("numberFrom", getError("numberFrom", "required"), false);
      errors["numberFrom"] = "required";
      isValid = false;
    } else if (!validFrom) {
      if (touched.numberFrom)
        showErr("numberFrom", getError("numberFrom", "nan"), false);
      errors["numberFrom"] = "nan";
      isValid = false;
    } else {
      showErr("numberFrom", "");
    }

    // Validate numberTo
    if (!val2) {
      if (touched.numberTo)
        showErr("numberTo", getError("numberTo", "required"), false);
      errors["numberTo"] = "required";
      isValid = false;
    } else if (!validTo) {
      if (touched.numberTo)
        showErr("numberTo", getError("numberTo", "nan"), false);
      errors["numberTo"] = "nan";
      isValid = false;
    } else {
      showErr("numberTo", "");
    }

    // Check range if both valid
    if (validFrom && validTo && numFrom >= numTo) {
      $form
        .find("#error-range")
        .html(
          `
      <span class="inail-span-error">
        <i class="fa-solid fa-circle-exclamation"></i> ${getError(
          "numberFrom",
          "rangeNum"
        )}
      </span>
    `
        )
        .show();
      errors["rangeNum"] = "rangeNum";
      isValid = false;
      $("#errorAnnouncer").remove();

      // Crea e appende nuovo div nascosto
      $("<div>", {
        id: "errorAnnouncer",
        role: "alert",
        "aria-live": "assertive",
        text: "Errore Intervallo numerico: Intervallo non corretto",
        class: "sr-only",
      }).appendTo("body");

      setTimeout(() => {
        $("#errorAnnouncer").remove();
      }, 500);
    } else {
      $form.find("#error-range").html("").hide();
    }

    return { isValid, errors };
  }

  // ========== Field Event Bindings ==========

  const fieldsToValidate = [
    "nome",
    "surname",
    "email",
    "gender",
    "birthday",
    "phone",
    "city",
    "address",
    "cap",
    "employer",
    "biografia",
  ];

  const lastErrorTexts = {};

  fieldsToValidate.forEach((f) => {
    if (!f) return;

    const $input = $form.find("#" + f);

    // Validazione su input/change: sempre valida e aggiorna l'errore
    $input.on("input change", () => {
      validateField(f);

      const errorText = $form
        .find(`#error-${f} .inail-span-error`)
        .text()
        .trim();
      lastErrorTexts[f] = errorText;
    });

    // Validazione su blur: solo se l'errore è cambiato o non presente
    $input.on("blur", () => {
      const $errorSpan = $form.find(`#error-${f} .inail-span-error`);
      const currentErrorText = $errorSpan.text().trim();

      // Se non è mai stato settato, non considerarlo cambiato
      const hasPreviousError = Object.prototype.hasOwnProperty.call(
        lastErrorTexts,
        f
      );
      const previousErrorText = hasPreviousError ? lastErrorTexts[f] : null;

      const noError = !$errorSpan.length;
      const errorChanged =
        hasPreviousError && currentErrorText !== previousErrorText;

      if (noError || errorChanged) {
        validateField(f);

        // Aggiorna l'errore solo dopo che è stato rigenerato
        setTimeout(() => {
          const updatedText = $form
            .find(`#error-${f} .inail-span-error`)
            .text()
            .trim();
          lastErrorTexts[f] = updatedText;
        });
      }
    });
  });

  $form.find("#numberFrom").on("input change", () => {
    touched.numberFrom = true;
    validateNumbers();

    const errorText = $form
      .find("#error-numberFrom .inail-span-error")
      .text()
      .trim();
    lastErrorTexts.numberFrom = errorText;
  });

  $form.find("#numberTo").on("input change", () => {
    touched.numberTo = true;
    validateNumbers();

    const errorText = $form
      .find("#error-numberTo .inail-span-error")
      .text()
      .trim();
    lastErrorTexts.numberTo = errorText;
  });

  $form.find("#numberFrom").on("blur", () => {
    touched.numberFrom = true;
    const $errorSpan = $form.find("#error-numberFrom .inail-span-error");
    const currentErrorText = $errorSpan.text().trim();
    const hasPreviousError = Object.prototype.hasOwnProperty.call(
      lastErrorTexts,
      "numberFrom"
    );
    const previousErrorText = hasPreviousError
      ? lastErrorTexts.numberFrom
      : null;

    const noError = !$errorSpan.length;
    const errorChanged =
      hasPreviousError && currentErrorText !== previousErrorText;

    if (noError || errorChanged) {
      validateNumbers();

      setTimeout(() => {
        const updatedText = $form
          .find("#error-numberFrom .inail-span-error")
          .text()
          .trim();
        lastErrorTexts.numberFrom = updatedText;
      });
    }
  });

  $form.find("#numberTo").on("blur", () => {
    touched.numberTo = true;
    const $errorSpan = $form.find("#error-numberTo .inail-span-error");
    const currentErrorText = $errorSpan.text().trim();
    const hasPreviousError = Object.prototype.hasOwnProperty.call(
      lastErrorTexts,
      "numberTo"
    );
    const previousErrorText = hasPreviousError ? lastErrorTexts.numberTo : null;

    const noError = !$errorSpan.length;
    const errorChanged =
      hasPreviousError && currentErrorText !== previousErrorText;

    if (noError || errorChanged) {
      validateNumbers();

      setTimeout(() => {
        const updatedText = $form
          .find("#error-numberTo .inail-span-error")
          .text()
          .trim();
        lastErrorTexts.numberTo = updatedText;
      });
    }
  });

  // AFTER renderOptions for radios and BEFORE your submit validation or other bindings:
  const $civilStatus = $form.find("#civilStatus");

  $civilStatus.on("focusin", 'input[name="statoCivile"]', () => {
    // $civilStatus.removeClass("inail-radio-group-error");
    // $("#error-civilStatus").empty();
  });

  $civilStatus.on("focusout change", 'input[name="statoCivile"]', () => {
    const selected = $form.find('input[name="statoCivile"]:checked').length;
    const $errorContainer = $form.find("#error-civilStatus");
    const $errorSpan = $errorContainer.find(".inail-span-error");
    const currentErrorText = $errorSpan.text().trim();

    const hasPreviousError = Object.prototype.hasOwnProperty.call(
      lastErrorTexts,
      "civilStatus"
    );
    const previousErrorText = hasPreviousError
      ? lastErrorTexts.civilStatus
      : null;

    const noError = !$errorSpan.length;
    const errorChanged =
      hasPreviousError && currentErrorText !== previousErrorText;

    // Se non c'è errore oppure l'errore è cambiato, valida

    if (selected === 0) {
      if (noError || errorChanged) {
        $civilStatus.addClass("inail-radio-group-error");
        $errorContainer.html(`
        <span class="inail-span-error">
          <i class="fa-solid fa-circle-exclamation"></i> Errore Stato civile: Campo obbligatorio.
        </span>
      `);

        // Crea e appende nuovo div nascosto
        $("<div>", {
          id: "errorAnnouncer",
          role: "alert",
          "aria-live": "assertive",
          text: "Errore Stato civile: Campo obbligatorio.",
          class: "sr-only",
        }).appendTo("body");

        setTimeout(() => {
          $("#errorAnnouncer").remove();
        }, 500);
      }

      // Aggiorna l'errore dopo il rendering
      setTimeout(() => {
        const updatedText = $form
          .find("#error-civilStatus .inail-span-error")
          .text()
          .trim();
        lastErrorTexts.civilStatus = updatedText;
      });
    } else {
      $civilStatus.removeClass("inail-radio-group-error");
      $errorContainer.empty();
    }
  });

  $form
    .find("#documentsContainer")
    .on("change blur", "input[type=checkbox]", () => {
      const $errorSpan = $form.find("#error-documents .inail-span-error");
      const currentErrorText = $errorSpan.text().trim();

      const hasPreviousError = Object.prototype.hasOwnProperty.call(
        lastErrorTexts,
        "documents"
      );
      const previousErrorText = hasPreviousError
        ? lastErrorTexts.documents
        : null;

      const noError = !$errorSpan.length;
      const errorChanged =
        hasPreviousError && currentErrorText !== previousErrorText;

      validateCheckbox(true, currentErrorText);

      setTimeout(() => {
        const updatedText = $form
          .find("#error-documents .inail-span-error")
          .text()
          .trim();
        lastErrorTexts.documents = updatedText;
      });
    });

  $form.find("#dateFrom").on("input change", () => {
    touchedDateRange.touchedDateFrom = true;
    validateDates();

    const errorText = $form
      .find("#error-dateFrom .inail-span-error")
      .text()
      .trim();
    lastErrorTexts.dateFrom = errorText;
  });

  $form.find("#dateTo").on("input change", () => {
    touchedDateRange.touchedDateTo = true;
    validateDates();

    const errorText = $form
      .find("#error-dateTo .inail-span-error")
      .text()
      .trim();
    lastErrorTexts.dateTo = errorText;
  });

  $("#dateFrom").on("blur", () => {
    touchedDateRange.touchedDateFrom = true;
    const $errorSpan = $form.find("#error-dateFrom .inail-span-error");
    const currentErrorText = $errorSpan.text().trim();
    const hasPreviousError = Object.prototype.hasOwnProperty.call(
      lastErrorTexts,
      "dateFrom"
    );
    const previousErrorText = hasPreviousError ? lastErrorTexts.dateFrom : null;

    const noError = !$errorSpan.length;
    const errorChanged =
      hasPreviousError && currentErrorText !== previousErrorText;

    if (noError || errorChanged) {
      validateDates();

      setTimeout(() => {
        const updatedText = $form
          .find("#error-dateFrom .inail-span-error")
          .text()
          .trim();
        lastErrorTexts.dateFrom = updatedText;
      });
    }
  });

  $form.find("#dateTo").on("blur", () => {
    touchedDateRange.touchedDateTo = true;
    const $errorSpan = $form.find("#error-dateTo .inail-span-error");
    const hasPreviousError = Object.prototype.hasOwnProperty.call(
      lastErrorTexts,
      "dateTo"
    );
    const currentErrorText = $errorSpan.text().trim();
    const previousErrorText = hasPreviousError ? lastErrorTexts.dateTo : null;

    const noError = !$errorSpan.length;
    const errorChanged =
      hasPreviousError && currentErrorText !== previousErrorText;

    if (noError || errorChanged) {
      validateDates();

      setTimeout(() => {
        const updatedText = $form
          .find("#error-dateTo .inail-span-error")
          .text()
          .trim();
        lastErrorTexts.dateTo = updatedText;
      });
    }
  });

  // $("[data-input-type='multiselect']").each(function () {
  //   const $input = $(this);
  //   const $dropdown = $input.siblings(".inail-multiselect-dropdown-menu");
  //   const field = $input.attr("id");
  //   const dropdownId = $dropdown.attr("id");

  //   function isFocusWithin() {
  //     const $focused = $(document.activeElement);
  //     return $input.is($focused) || $.contains($dropdown[0], $focused[0]);
  //   }

  //   $input.add($dropdown).on("focusout", () => {
  //     const $errorSpan = $("#error-patenti .inail-span-error");
  //     const currentErrorText = $errorSpan.text().trim();

  //     setTimeout(() => {
  //       if (!isFocusWithin()) {
  //         const errori = validateMulti(field, dropdownId);
  //         if (errori.errors.patenti == "minLength") {
  //           if (currentErrorText !== ('Errore Patenti: Minimo 2 elementi richiesti.').trim()) {
  //             $("#errorAnnouncer").text('Errore Patenti: Minimo 2 elementi richiesti.');
  //             // setTimeout(() => $("#errorAnnouncer").text(""), 100);
  //           }
  //         } else if (errori.errors.patenti == "required") {
  //           if (currentErrorText !== ('Errore Patenti: Campo obbligatorio.').trim()) {
  //             $("#errorAnnouncer").text('Errore Patenti: Campo obbligatorio.');
  //             // setTimeout(() => $("#errorAnnouncer").text(""), 100);
  //           }
  //         }
  //       }
  //     }, 0);

  //     setTimeout(() => {
  //       const updatedText = $("#error-patenti .inail-span-error").text().trim();
  //       lastErrorTexts.patenti = updatedText;
  //     });
  //   });
  // });

  $form.find("[data-input-type='multiselect']").each(function () {
    const $input = $form.find(this);
    const $dropdown = $input.siblings(".inail-multiselect-dropdown-menu");
    const $container = $input.closest(".dropdown");
    const field = $input.attr("id");
    const dropdownId = $dropdown.attr("id");

    let $errorSpan = $form.find("#error-patenti .inail-span-error");
    let currentErrorText = $errorSpan.text().trim();

    let userInteracted = false;

    function isFocusWithin() {
      const $focused = $form.find(document.activeElement);
      return $input.is($focused) || $.contains($dropdown[0], $focused[0]);
    }

    // Mark user interaction on checkbox change
    $dropdown.on("change", ".option-checkbox", function () {
      $errorSpan = $form.find("#error-patenti .inail-span-error");
      currentErrorText = $errorSpan.text().trim();

      setTimeout(() => {
        const updatedText = $form
          .find("#error-patenti .inail-span-error")
          .text()
          .trim();
        lastErrorTexts.patenti = updatedText;
      });

      userInteracted = true;
    });

    // Reset interaction flag when dropdown opens (input clicked)
    $input.on("click", function () {
      $errorSpan = $form.find("#error-patenti .inail-span-error");
      currentErrorText = $errorSpan.text().trim();

      setTimeout(() => {
        const updatedText = $form
          .find("#error-patenti .inail-span-error")
          .text()
          .trim();
        lastErrorTexts.patenti = updatedText;
      });
      userInteracted = false;
      $dropdown.show();
    });

    // On focusout always validate (required check)
    $input.add($dropdown).on("focusout", () => {
      $errorSpan = $form.find("#error-patenti .inail-span-error");
      currentErrorText = $errorSpan.text().trim();

      setTimeout(() => {
        const updatedText = $form
          .find("#error-patenti .inail-span-error")
          .text()
          .trim();
        lastErrorTexts.patenti = updatedText;
      });

      setTimeout(() => {
        if (!$dropdown.is(":visible") && !isFocusWithin()) {
          validateMulti(field, dropdownId, true, 2, currentErrorText);
        }
      }, 0);
    });

    // On outside click validate only if user interacted
    $form.find(document).on("mousedown", function (e) {
      $errorSpan = $form.find("#error-patenti .inail-span-error");
      currentErrorText = $errorSpan.text().trim();

      setTimeout(() => {
        const updatedText = $form
          .find("#error-patenti .inail-span-error")
          .text()
          .trim();
        lastErrorTexts.patenti = updatedText;
      });

      const isClickInside =
        $container.is(e.target) || $container.has(e.target).length > 0;

      if (!isClickInside) {
        $dropdown.hide();

        setTimeout(() => {
          if (!$dropdown.is(":visible") && userInteracted) {
            validateMulti(field, dropdownId, true, 2, currentErrorText);
          }
        }, 0);
      }
    });
  });

  $form
    .find("#biografia")
    .on("input", () =>
      $form
        .find("#count-biografia")
        .text($form.find("#biografia").val()?.toString().length || 0)
    );

  // ========== Submit Validation ==========

  $form.on("submit", function (e) {
    e.preventDefault();

    $("#errorAnnouncer").remove();

    let valid = true;
    const errorMap = {};

    // Reset summary
    $("#error-summary").empty().hide();

    // Validate single fields
    fieldsToValidate.forEach((f) => {
      const result = validateField(f);
      const val =
        $form
          .find("#" + f)
          .val()
          ?.toString()
          .trim() || "";
      if (!result) {
        errorMap[f] = getErrorFeedback(
          f,
          f === "email" && val ? "email" : "required"
        );
        valid = false;
      }
    });

    // Mark all as touched
    touched.numberFrom = true;
    touched.numberTo = true;
    touchedDateRange.touchedDateFrom = true;
    touchedDateRange.touchedDateTo = true;

    // Number range validation
    const numberValidation = validateNumbers();

    if (!numberValidation.isValid) {
      if (numberValidation.errors["numberFrom"]) {
        errorMap["numberFrom"] = getErrorFeedback(
          "numberFrom",
          numberValidation.errors["numberFrom"]
        );
      }

      if (numberValidation.errors["numberTo"]) {
        errorMap["numberTo"] = getErrorFeedback(
          "numberTo",
          numberValidation.errors["numberTo"]
        );
      }

      if (numberValidation.errors["rangeNum"]) {
        errorMap["rangeNum"] = getErrorFeedback("numberFrom", "rangeNum");
      }

      valid = false;
    }

    // Date validation
    const dateValidation = validateDates();

    if (!dateValidation.isValid) {
      if (dateValidation.errors["dateFrom"]) {
        errorMap["dateFrom"] = getErrorFeedback(
          "dateFrom",
          dateValidation.errors["dateFrom"]
        );
      }
      if (dateValidation.errors["dateTo"]) {
        errorMap["dateTo"] = getErrorFeedback(
          "dateTo",
          dateValidation.errors["dateTo"]
        );
      }
      valid = false;
    }

    // Multi-select validation
    const multiValidation = validateMulti("patenti", "licenseTypes", false);

    if (!multiValidation.isValid) {
      const errorType = multiValidation.errors["patenti"];
      if (errorType) {
        errorMap["patenti"] = getErrorFeedback("patenti", errorType);
      }
      valid = false;
    }

    // Radio button validation
    if (!validateRadio()) {
      errorMap["statoCivile"] = getErrorFeedback("statoCivile", "required");
      valid = false;
    }

    // Checkbox validation
    const checkboxValidation = validateCheckbox(false);

    if (!checkboxValidation.isValid) {
      const errorType = checkboxValidation.errors["documents"];
      if (errorType) {
        errorMap["documents"] = getErrorFeedback("documents", errorType);
      }
      valid = false;
    }
    //////////////////////////////

    if (!valid) {
      // Clear previous errors first
      $("#feedback-container").empty();

      const errorEntries = Object.entries(errorMap);

      const feedbackHtml = `
  <div role="group" aria-labelledby="feedback-title" data-type="feedback">
    <div role="alert">
      <div class="inail-feedback-header inail-feedback-header-negative inail-regular-border-bottom align-items-center d-flex justify-content-between">
        <span class="inail-feedback-title" id="feedback-title">
          <span class="fa fa-exclamation-triangle mr-2"></span>
          <span class="sr-only">Feedback negativo</span>
          Errore nell'azione
        </span>
        <button class="fa fa-xmark inail-feedback-close-button bg-transparent border-0" aria-label="Chiudi messaggio di feedback" id="close-feedback-button"></button>
      </div>
      <div class="inail-feedback-container">
        <div id="error-summary" tabindex="-1">
          <div id="form-error-count" class="mb-2">Sono presenti ${
            errorEntries.length
          } errori nel form. Correggere i seguenti campi:</div>
          <div id="form-error-list">
            ${errorEntries
              .map(([field, message], i) => {
                const label = labelsFeedback[field] || field;
                return `
                <div class="error-item d-flex" style="margin-bottom: 4px;">
                  <div style="width: 28px;">${i + 1}.</div>
                  <div>${label}: ${message}.</div>
                </div>
              `;
              })
              .join("")}
          </div>
        </div>
      </div>
    </div>
  </div>
`;
      $("#feedback-container").html(feedbackHtml);

      $('[data-type="feedback"]').show();

      $("#close-feedback-button").on("click", function () {
        $(this).closest('div[data-type="feedback"]').remove();
      });

      $("html, body").animate(
        { scrollTop: $("#feedback-container").offset()?.top || 0 },
        300
      );
      $form.find("#nome").focus();
    } else {
      $('[data-type="feedback"]').remove();

      $("#feedback-container").empty();
    }
  });
});
