(function ($) {
  $(document).ready(function () {

    $('#showMore').click(function(){
      setTimeout(() => {
      if($(this).attr('aria-expanded')== 'true'){
        $('#textShowMore').html('Nascondi opzioni')
      }
      else $('#textShowMore').html('Altre opzioni')
      
      }, 100); 
    })

    const $form = $("#form-with-validation");

    const cityListFWV = [
      "Roma",
      "Milano",
      "Torino",
      "Napoli",
      "Bologna",
      "Firenze",
      "Genova",
      "Cagliari",
      "Udine",
      "Caserta",
    ];
    const licenseTypesFWV = ["A1", "A", "B", "C", "D"];
    const radioOptionsFWV = [
      "Celibe/Nubile",
      "Sposato/a",
      "Divorziato/a",
      "Vedovo/a",
    ];
    const checkboxDocsFWV = [
      "Carta d'identità",
      "Patente",
      "Passaporto",
      "Tessera sanitaria",
    ];
    const fieldsToValidate = [
      "fwv-nome",
      "fwv-surname",
      "fwv-email",
      "fwv-gender",
      "fwv-birthday",
      "fwv-phone",
      "fwv-city",
      "fwv-address",
      "fwv-cap",
      "fwv-employer",
      "fwv-biografia",
    ];

    checkFormCompleteness();
    // ========== Render dynamic options ==========
    function renderOptions(id, items, renderFn) {
      items.forEach((item, index) => {
        $form.find("#" + id).append(renderFn(item, index));
      });
    }
    renderOptions("cityListFWV", cityListFWV, function (c) {
      return `<div class="option" tabindex="0" value="${c}">${c}</div>`;
    });
    renderOptions("licenseTypesFWV", licenseTypesFWV, 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("statoContainerFWV", radioOptionsFWV, function (o) {
      return `
        <div class="col-lg-3 col-md-3 col-sm-6 col-xs-12 p-0">
          <label class="inail-radio-button">
            <input type="radio" name="statoCivile" class="inail-radio-input" value="${o}" checked>
            <div class="inail-radio-background">
              <div class="inail-radio-inner-circle"></div>
            </div>
            ${o}
          </label>
        </div>`;
    });
    renderOptions("documentsContainerFWV", checkboxDocsFWV, 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 ==========

    let labelsFWV = {
      "fwv-nome": "Nome",
      "fwv-surname": "Cognome",
      "fwv-email": "Email",
      "fwv-gender": "Sesso",
      "fwv-birthday": "Data di nascita",
      "fwv-phone": "Telefono",
      "fwv-city": "Città",
      "fwv-address": "Indirizzo",
      "fwv-cap": "CAP",
      "fwv-biografia": "Biografia",
      "fwv-dateFrom": "Dal",
      "fwv-dateTo": "Al",
      "fwv-numberFrom": "Da",
      "fwv-numberTo": "A",
      "fwv-patenti": "Patenti",
      "fwv-statoCivile": "Stato civile",
      "fwv-documents": "Documenti allegati",
      "fwv-employer": "Ultima occupazione",
    };
    function getError(field, type) {
      if (type === "required")
        return "Errore " + labelsFWV[field] + ": Campo obbligatorio.";
      if (type === "email") return "Indirizzo email non valido.";
      if (type === "minLength")
        return "Errore " + labelsFWV[field] + ": Minimo 2 elementi richiesti.";
      if (type === "rangeDate")
        return (
          "Errore " +
          labelsFWV[field] +
          ":La data di inizio deve precedere la fine."
        );
      if (type === "nan")
        return "Errore " + labelsFWV[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 "";
    }

    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 === "fwv-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 === "fwv-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("fwv-statoCivile", "required") : "";
      showGroupError(msg, "#fwv-civilStatus", "#error-fwv-civilStatus");
      return !msg;
    }

    function validateCheckbox(announceError = true, currentErrorText) {
      const selected = $form.find('input[name="documents"]:checked').length;
      const field = "fwv-documents";
      const containerSelector = "#documentsContainerFWV";
      const errorSelector = "#error-fwv-documents";
      let msg = "";
      let isValid = true;
      const errors = {};

      // Remove any previous error announcer if exists
      $("#errorAnnouncer").remove();

      if (selected === 0) {
        msg = getError(field, "required");
        errors[field] = "required";
        isValid = false;

        if (currentErrorText !== msg.trim() && announceError) {
          // Create and append new hidden error announcer
          $("<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) {
          $("<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);

      // Add or remove error class on checkboxes
      $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("#fwv-dateFrom").val()?.toString().trim() || "";
      const valTo = $form.find("#fwv-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("fwv-dateFrom", getError("fwv-dateFrom", "required"), false);
        errors["fwv-dateFrom"] = "required";
        isValid = false;
      } else if (!dateFrom) {
        if (touchedDateRange.touchedDateFrom)
          showErr(
            "fwv-dateFrom",
            getError("fwv-dateFrom", "dateFormat"),
            false
          );
        errors["fwv-dateFrom"] = "dateFormat";
        isValid = false;
      } else {
        showErr("fwv-dateFrom", "");
      }

      // Validate dateTo
      if (!valTo) {
        if (touchedDateRange.touchedDateTo)
          showErr("fwv-dateTo", getError("fwv-dateTo", "required"), false);
        errors["fwv-dateTo"] = "required";
        isValid = false;
      } else if (!dateTo) {
        if (touchedDateRange.touchedDateTo)
          showErr("fwv-dateTo", getError("fwv-dateTo", "dateFormat"), false);
        errors["fwv-dateTo"] = "dateFormat";
        isValid = false;
      } else if (
        dateFrom &&
        touchedDateRange.touchedDateFrom &&
        touchedDateRange.touchedDateTo &&
        dateTo <= dateFrom
      ) {
        showErr("fwv-dateTo", getError("fwv-dateTo", "rangeDate"), false);
        errors["fwv-dateTo"] = "rangeDate";
        isValid = false;
      } else {
        showErr("fwv-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-fwv-range").hide().empty();
      showErr("fwv-numberFrom", "");
      showErr("fwv-numberTo", "");
    }

    function validateNumbers() {
      const val1 = $form.find("#fwv-numberFrom").val()?.toString().trim() || "";
      const val2 = $form.find("#fwv-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(
            "fwv-numberFrom",
            getError("fwv-numberFrom", "required"),
            false
          );
        errors["fwv-numberFrom"] = "required";
        isValid = false;
      } else if (!validFrom) {
        if (touched.numberFrom)
          showErr("fwv-numberFrom", getError("fwv-numberFrom", "nan"), false);
        errors["fwv-numberFrom"] = "nan";
        isValid = false;
      } else {
        showErr("fwv-numberFrom", "");
      }

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

      // Check range if both valid
      if (validFrom && validTo && numFrom >= numTo) {
        $form
          .find("#error-fwv-range")
          .html(
            `
      <span class="inail-span-error">
        <i class="fa-solid fa-circle-exclamation"></i> ${getError(
          "fwv-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-fwv-range").html("").hide();
      }

      return { isValid, errors };
    }

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

    function checkFormCompleteness() {
      let allValid = true;

      // Validate required text/select fields
      for (const fieldId of fieldsToValidate) {
        const $el = $form.find(`#${fieldId}`);
        const val = ($el.val() || "").toString().trim();

        if ($el.is("select") && val === "") {
          allValid = false;
          break;
        } else if (fieldId === "fwv-email" && !/^\S+@\S+\.\S+$/.test(val)) {
          allValid = false;
          break;
        }

        if (!$el.is("select") && !val) {
          allValid = false;
          break;
        }
      }

      // Validate radio group (stato civile)
      if ($form.find('input[name="statoCivile"]:checked').length === 0) {
        allValid = false;
      }

      // Validate document checkboxes (min 2)
      if ($form.find('input[name="documents"]:checked').length < 2) {
        allValid = false;
      }

      // Validate license checkboxes (min 2)
      if (
        $form.find("#licenseTypesFWV input[type=checkbox]:checked").length < 2
      ) {
        allValid = false;
      }

      // Validate date range
      const dateFromVal = ($form.find("#fwv-dateFrom").val() || "").trim();
      const dateToVal = ($form.find("#fwv-dateTo").val() || "").trim();
      const dateFrom = parseDate(dateFromVal);
      const dateTo = parseDate(dateToVal);

      if (!dateFrom || !dateTo || dateTo <= dateFrom) {
        allValid = false;
      }

      // Validate number range
      const numFromVal = ($form.find("#fwv-numberFrom").val() || "").trim();
      const numToVal = ($form.find("#fwv-numberTo").val() || "").trim();
      const numFrom = parseFloat(numFromVal);
      const numTo = parseFloat(numToVal);

      if (
        !numFromVal ||
        !numToVal ||
        isNaN(numFrom) ||
        isNaN(numTo) ||
        numFrom >= numTo
      ) {
        allValid = false;
      }

      // Enable or disable submit button
      $form
        .find('button[type="submit"], input[type="submit"]')
        .prop("disabled", !allValid);

      return allValid;
    }

    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("#fwv-numberFrom").on("input change", () => {
      touched.numberFrom = true;
      validateNumbers();

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

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

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

    $form.find("#fwv-numberFrom").on("blur", () => {
      touched.numberFrom = true;
      const $errorSpan = $form.find("#error-fwv-numberFrom .inail-span-error");
      const currentErrorText = $errorSpan.text().trim();
      const hasPreviousError = Object.prototype.hasOwnProperty.call(
        lastErrorTexts,
        "fwv-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-fwv-numberFrom .inail-span-error")
            .text()
            .trim();
          lastErrorTexts.numberFrom = updatedText;
        });
      }
    });

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

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

      if (noError || errorChanged) {
        validateNumbers();
        // Aggiungi questa riga

        setTimeout(() => {
          const updatedText = $form
            .find("#error-fwv-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("#fwv-civilStatus");

    $civilStatus.on("focusout change", 'input[name="statoCivile"]', () => {
      const selected = $form.find('input[name="statoCivile"]:checked').length;
      const $errorContainer = $form.find("#error-fwv-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-fwv-civilStatus .inail-span-error")
            .text()
            .trim();
          lastErrorTexts.civilStatus = updatedText;
        });
      } else {
        $civilStatus.removeClass("inail-radio-group-error");
        $errorContainer.empty();
      }
    });

    // Event delegation on checkboxes inside #documentsContainerFWV
    $form
      .find("#documentsContainerFWV")
      .on("change blur", "input[type=checkbox]", () => {
        const $errorSpan = $form.find("#error-fwv-documents .inail-span-error");
        const currentErrorText = $errorSpan.text().trim();

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

        validateCheckbox(true, currentErrorText);

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

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

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

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

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

    $form.find("#fwv-dateFrom").on("blur", () => {
      touchedDateRange.touchedDateFrom = true;
      const $errorSpan = $form.find("#error-fwv-dateFrom .inail-span-error");
      const currentErrorText = $errorSpan.text().trim();
      const hasPreviousError = Object.prototype.hasOwnProperty.call(
        lastErrorTexts,
        "fwv-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-fwv-dateFrom .inail-span-error")
            .text()
            .trim();
          lastErrorTexts.dateFrom = updatedText;
        });
      }
    });

    $form.find("#fwv-dateTo").on("blur", () => {
      touchedDateRange.touchedDateTo = true;
      const $errorSpan = $form.find("#error-fwv-dateTo .inail-span-error");
      const hasPreviousError = Object.prototype.hasOwnProperty.call(
        lastErrorTexts,
        "fwv-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-fwv-dateTo .inail-span-error")
            .text()
            .trim();
          lastErrorTexts.dateTo = updatedText;
        });
      }
    });

    $form.find("[data-input-type='multiselect']").each(function () {
      const $input = $(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-fwv-patenti .inail-span-error");
      let currentErrorText = $errorSpan.text().trim();

      let userInteracted = false;

      function isFocusWithin() {
        const $focused = $(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-fwv-patenti .inail-span-error");
        currentErrorText = $errorSpan.text().trim();

        setTimeout(() => {
          const updatedText = $form
            .find("#error-fwv-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-fwv-patenti .inail-span-error");
        currentErrorText = $errorSpan.text().trim();

        setTimeout(() => {
          const updatedText = $form
            .find("#error-fwv-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-fwv-patenti .inail-span-error");
        currentErrorText = $errorSpan.text().trim();

        setTimeout(() => {
          const updatedText = $form
            .find("#error-fwv-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
      $(document).on("mousedown", function (e) {
        $errorSpan = $form.find("#error-fwv-patenti .inail-span-error");
        currentErrorText = $errorSpan.text().trim();

        setTimeout(() => {
          const updatedText = $form
            .find("#error-fwv-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("#fwv-biografia")
      .on("input", () =>
        $form
          .find("#count-fwv-biografia")
          .text($form.find("#fwv-biografia").val()?.toString().length || 0)
      );

    $form.on("input change", "input, select, textarea", checkFormCompleteness);
    $form.on(
      "change",
      "input[type=checkbox], input[type=radio]",
      checkFormCompleteness
    );
    // ========== Submit Validation ==========

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

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

      let valid = true;
      const errorMap = {};

      // Validate single fields
      fieldsToValidate.forEach((f) => {
        const result = validateField(f);
        const val =
          $form
            .find("#" + f)
            .val()
            ?.toString()
            .trim() || "";
        if (!result) {
          errorMap[f] = getError(
            f,
            f === "fwv-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["fwv-numberFrom"]) {
          errorMap["fwv-numberFrom"] = getError(
            "fwv-numberFrom",
            numberValidation.errors["fwv-numberFrom"]
          );
        }

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

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

        valid = false;
      }

      // Date validation
      const dateValidation = validateDates();

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

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

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

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

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

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

      if (!valid) {
      } else {
      }
    });
  });
})(jQuery);
