<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script>

    function loading(text = 'Cargando...') {
        Swal.fire({
            title: text,
            allowEscapeKey: false,
            allowOutsideClick: false,
            didOpen: () => Swal.showLoading()
        });
    }

    function stopLoading() {
        Swal.close();
    }


    function validator(fields = []) {
        let isValidForm = true;

        fields.forEach(selector => {
            const field = document.querySelector(selector);
            if (!field) return;

            clearError(field);
            removeImagePreview(field); // limpia preview previo

            const rules = field.dataset.validate?.split(",") || [];

            rules.forEach(rule => {
                rule = rule.trim();

                switch (rule) {

                    case "required":
                        if (!validateRequired(field.value)) {
                            showError(field, "Este campo es obligatorio.");
                        }
                        break;

                    case "email":
                        if (!validateEmail(field.value)) {
                            showError(field, "El correo no es válido.");
                        }
                        break;

                    case "rut":
                        if (!validateRut(field.value)) {
                            showError(field, "El RUT no es válido.");
                        } else {
                            field.value = formatRut(field.value); // ✔ formatear automáticamente
                        }
                        break;

                    case "chile-phone":
                        if (!validatePhone(field.value)) {
                            showError(field, "El número debe comenzar con +569.");
                        }
                        break;

                    case "min-length":
                        const min = parseInt(field.dataset.minLength || "0");
                        if (field.value.length < min) {
                            showError(field, `Debe tener al menos ${min} caracteres.`);
                        }
                        break;

                    case "max-length":
                        const max = parseInt(field.dataset.maxLength || "999999");
                        if (field.value.length > max) {
                            showError(field, `No puede exceder ${max} caracteres.`);
                        }
                        break;

                    case "file-extension":
                        const allowedExt = (field.dataset.fileExtension || "").split(",");
                        if (!validateFileExtension(field, allowedExt)) {
                            showError(field, `Archivo no permitido (${allowedExt.join(", ")})`);
                        }
                        break;

                    case "max-file-size":
                        const maxSize = parseInt(field.dataset.maxFileSize || "0");
                        if (!validateFileSize(field, maxSize)) {
                            showError(field, `El archivo supera ${maxSize} KB.`);
                        }
                        break;

                    case "min-file-size":
                        const minSize = parseInt(field.dataset.minFileSize || "0");
                        if (!validateFileMinSize(field, minSize)) {
                            showError(field, `El archivo debe pesar más de ${minSize} KB.`);
                        }
                        break;

                    case "comparewith":
                        const otherSelector = field.dataset.validateCompareId;
                        const otherField = document.querySelector(otherSelector);

                        if (!otherField) {
                            showError(field, `El campo a comparar (${otherSelector}) no existe.`);
                            break;
                        }

                        if (field.value !== otherField.value) {
                            showError(field, "Los valores no coinciden.");
                        }
                    break;
                }
            });

            // Mostrar preview si corresponde y si no tiene errores
            if (field.type === "file" && !field.classList.contains("is-invalid")) {
                showImagePreview(field);
            }

            if (field.classList.contains("is-invalid")) {
                isValidForm = false;
            }
        });

        return isValidForm;
    }


    ///////////////////////////////////////////////////////
    // MANEJO DE ERRORES
    ///////////////////////////////////////////////////////

    function clearError(field) {
        field.classList.remove("is-invalid");

        const next = field.nextElementSibling;
        if (next && next.classList.contains("invalid-feedback")) {
            next.remove();
        }
    }

    function showError(field, message) {
        if (!field.classList.contains("is-invalid")) {
            field.classList.add("is-invalid");

            const feedback = document.createElement("div");
            feedback.className = "invalid-feedback";
            feedback.textContent = message;

            field.insertAdjacentElement("afterend", feedback);
        }
    }

    ///////////////////////////////////////////////////////
    // VALIDACIÓN BÁSICA
    ///////////////////////////////////////////////////////

    function validateRequired(value) {
        return value.trim() !== "";
    }

    function validateEmail(value) {
        const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return regex.test(value);
    }

    ///////////////////////////////////////////////////////
    // ✔ VALIDAR Y FORMATEAR RUT
    ///////////////////////////////////////////////////////

    function validateRut(rut) {
        rut = rut.replace(/\./g, "").replace("-", "");
        if (rut.length < 8) return false;

        const cuerpo = rut.slice(0, -1);
        let dv = rut.slice(-1).toUpperCase();

        let suma = 0, multiplicador = 2;

        for (let i = cuerpo.length - 1; i >= 0; i--) {
            suma += multiplicador * parseInt(cuerpo[i]);
            multiplicador = multiplicador < 7 ? multiplicador + 1 : 2;
        }

        let dvEsperado = 11 - (suma % 11);
        dvEsperado = dvEsperado === 11 ? "0" : dvEsperado === 10 ? "K" : dvEsperado.toString();

        return dv === dvEsperado;
    }

    function formatRut(rut) {
        rut = rut.replace(/\./g, "").replace("-", "");
        const cuerpo = rut.slice(0, -1);
        const dv = rut.slice(-1).toUpperCase();

        const cuerpoMiles = cuerpo.replace(/\B(?=(\d{3})+(?!\d))/g, ".");
        return cuerpoMiles + "-" + dv;
    }

    ///////////////////////////////////////////////////////
    // VALIDACIÓN DE TELÉFONO
    ///////////////////////////////////////////////////////

    function validatePhone(value) {
        return /^(\+?56)?9\d{8}$/.test(value);
    }

    ///////////////////////////////////////////////////////
    // VALIDACIÓN DE ARCHIVOS
    ///////////////////////////////////////////////////////

    function validateFileExtension(field, allowed) {
        if (!field.files.length) return true;
        const ext = field.files[0].name.split('.').pop().toLowerCase();
        return allowed.includes(ext);
    }

    function validateFileSize(field, maxKB) {
        if (!field.files.length) return true;
        return (field.files[0].size / 1024) <= maxKB;
    }

    function validateFileMinSize(field, minKB) {
        if (!field.files.length) return true;
        return (field.files[0].size / 1024) >= minKB;
    }

    ///////////////////////////////////////////////////////
    // ✔ NUEVO: PREVIEW DE IMAGEN
    ///////////////////////////////////////////////////////

    function showImagePreview(field) {
        if (!field.files || !field.files[0]) return;

        const file = field.files[0];
        if (!file.type.startsWith("image/")) return;

        removeImagePreview(field);

        const img = document.createElement("img");
        img.src = URL.createObjectURL(file);
        img.style.maxWidth = "150px";
        img.style.marginTop = "8px";
        img.style.borderRadius = "4px";
        img.style.display = "block";
        img.className = "image-preview";

        field.insertAdjacentElement("afterend", img);
    }

    function removeImagePreview(field) {
        const next = field.nextElementSibling;
        if (next && next.classList.contains("image-preview")) {
            next.remove();
        }
    }

    /**
     * Agrega un asterisco rojo a todos los labels
     * que correspondan a campos con data-validate="required,..."
     */
    function markRequiredLabels() {
        const fields = document.querySelectorAll("[data-validate]");

        fields.forEach(field => {
            const rules = field.dataset.validate.split(",").map(r => r.trim());

            // Solo agregar si el campo es required
            if (!rules.includes("required")) return;

            // Buscar el label asociado
            const label = document.querySelector(`label[for="${field.id}"]`);
            if (!label) return;

            // Evita duplicar asterisco si se llama más de una vez
            if (label.dataset.requiredMarked) return;

            // Crear span con asterisco rojo
            const star = document.createElement("span");
            star.textContent = " *";
            star.style.color = "red";
            star.style.fontWeight = "bold";

            // Agregar al label
            label.appendChild(star);

            // Marca para evitar duplicación
            label.dataset.requiredMarked = "1";
        });
    }

    // Ejecutar al cargar la página
    document.addEventListener("DOMContentLoaded", markRequiredLabels);

</script>
