import { useState, useMemo } from "react";
import countries from "i18n-iso-countries";
import en from "i18n-iso-countries/langs/en.json";
import fr from "i18n-iso-countries/langs/fr.json";
import es from "i18n-iso-countries/langs/es.json";
import de from "i18n-iso-countries/langs/de.json";
import pt from "i18n-iso-countries/langs/pt.json";
import hi from "i18n-iso-countries/langs/hi.json";
import ru from "i18n-iso-countries/langs/ru.json";
import { ELocalesPlacement } from "@/locales";
import { useTranslations } from "@/hooks/translations";

const locales = [en, fr, es, de, pt, hi, ru];

locales.forEach(locale => {
    countries.registerLocale(locale);
});

export interface AddressFields {
    country: string;
    address: string;
    zip: string;
}

export function useAddressFields(locale: string = "en", initial?: Partial<AddressFields>) {
    const { translate } = useTranslations(ELocalesPlacement.V1);

    const [fields, setFields] = useState<AddressFields>({
        country: "",
        address: "",
        zip: "",
        ...initial,
    });
    const [errors, setErrors] = useState<Partial<Record<keyof AddressFields, string>>>({
        country: "",
        address: "",
        zip: "",
    });
    const [touched, setTouched] = useState<Partial<Record<keyof AddressFields, boolean>>>({
        country: false,
        address: false,
        zip: false,
    });

    const isValid = useMemo(() => {
        if (Object.values(touched).some(value => !value)) {
            return false;
        }
        return Object.values(errors).every(error => error === "");
    }, [errors, touched]);

    const countryList = useMemo(() => {
        let _locale = locale;
        if (locale === "es-419") {
            _locale = "es";
        }
        if (locale === "pt-BR" || locale === "pt-PT") {
            _locale = "pt";
        }
        if (!Object.keys(countries.getNames(_locale)).length) {
            _locale = "en";
        }
        const names = countries.getNames(_locale, { select: "official" });

        return Object.entries(names).map(([code, name]) => ({ code, name }));
    }, [locale]);

    const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
        setTouched({ ...touched, [e.target.name]: true });
        validate(e.target.name as keyof AddressFields, e.target.value);
        setFields({ ...fields, [e.target.name]: e.target.value });
    };

    const validate = (name: keyof AddressFields, value: string) => {
        switch (name) {
            case "country":
                if (!value) {
                    setErrors({ ...errors, country: translate("payment_modal.address_form.errors.country") });
                } else {
                    setErrors({ ...errors, country: "" });
                }
                break;
            case "address":
                if (!value) {
                    setErrors({ ...errors, address: translate("payment_modal.address_form.errors.address") });
                } else {
                    setErrors({ ...errors, address: "" });
                }
                break;
            case "zip":
                const country = fields.country || initial?.country || "";
                let zipValid = false;
                let zipError = "";

                const zipRegexes: Record<string, RegExp> = {
                    US: /^\d{5}(-\d{4})?$/, // 12345 или 12345-6789
                    GB: /^[A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}$/i, // SW1A 1AA
                    AU: /^\d{4}$/, // 4000
                    FR: /^\d{5}$/, // 75008
                    ES: /^\d{5}$/, // 28013
                    DE: /^\d{5}$/, // 10115
                    PT: /^\d{4}-\d{3}$/, // 1000-001
                    BR: /^\d{5}-?\d{3}$/, // 12345-678 или 12345678
                    IN: /^\d{6}$/, // 110001
                    RU: /^\d{6}$/, // 123456
                };

                if (!value) {
                    zipError = translate("payment_modal.address_form.errors.zip");
                } else if (country && zipRegexes[country]) {
                    zipValid = zipRegexes[country].test(value);
                    if (!zipValid) {
                        zipError = translate("payment_modal.address_form.errors.zip_invalid");
                    }
                } else {
                    zipValid = !!value;
                    if (!zipValid) {
                        zipError = translate("payment_modal.address_form.errors.zip");
                    }
                }

                setErrors({ ...errors, zip: zipError });
                break;
        }
    };

    const validateAll = () => {
        for (const key in fields) {
            validate(key as keyof AddressFields, fields[key as keyof AddressFields]);
        }
        return Object.values(errors).every(error => error === "");
    };

    return useMemo(() => ({
        fields,
        errors,
        handleChange,
        validate,
        validateAll,
        countryList,
        setFields,
        setErrors,
        isValid
    }), [
        fields,
        errors,
        handleChange,
        validate,
        validateAll,
        countryList,
        setFields,
        setErrors,
        isValid
    ]);
}