type AreaCodeType = { [key: string]: string };

const areaCodes: AreaCodeType = {
    "11": "AMBA",
    "220": "MERLO (PROV.  BUENOS AIRES)",
    "221": "LA PLATA",
    "223": "MAR DEL PLATA",
    "230": "PILAR (PROV.  BUENOS AIRES)",
    "236": "JUNIN (PROV.  BUENOS AIRES)",
    "237": "MORENO",
    "249": "TANDIL",
    "260": "SAN RAFAEL (PROV. MENDOZA)",
    "261": "MENDOZA",
    "263": "SAN MARTIN (PROV.  MENDOZA)",
    "264": "SAN JUAN",
    "266": "SAN LUIS (PROV. SAN LUIS)",
    "280": "TRELEW",
    "291": "BAHIA BLANCA",
    "294": "SAN CARLOS DE BARILOCHE",
    "297": "COMODORO RIVADAVIA",
    "298": "GENERAL ROCA (PROV.  RIO NEGRO)",
    "299": "NEUQUEN",
    "336": "SAN NICOLAS",
    "341": "ROSARIO",
    "342": "SANTA FE",
    "343": "PARANA",
    "345": "CONCORDIA",
    "348": "ESCOBAR",
    "351": "CORDOBA",
    "353": "VILLA MARIA",
    "358": "RIO CUARTO",
    "362": "RESISTENCIA",
    "364": "PRESIDENCIA ROQUE SAENZ PEÑA",
    "370": "FORMOSA",
    "376": "POSADAS",
    "379": "CORRIENTES",
    "380": "LA RIOJA",
    "381": "SAN MIGUEL DE TUCUMAN",
    "383": "CATAMARCA",
    "385": "SANTIAGO DEL ESTERO",
    "387": "SALTA",
    "388": "SAN SALVADOR DE JUJUY",
    "2202": "GONZALEZ CATAN",
    "2221": "MAGDALENA",
    "2223": "CORONEL BRANDSEN",
    "2224": "GLEW",
    "2225": "ALEJANDRO KORN",
    "2226": "CAÑUELAS",
    "2227": "LOBOS",
    "2229": "JUAN MARIA GUTIERREZ",
    "2241": "CHASCOMUS",
    "2242": "LEZAMA",
    "2243": "GENERAL BELGRANO",
    "2244": "LAS FLORES (PROV.  BUENOS AIRES)",
    "2245": "DOLORES (PROV.  BUENOS AIRES)",
    "2246": "SANTA TERESITA",
    "2252": "SAN CLEMENTE DEL TUYU",
    "2254": "PINAMAR",
    "2255": "VILLA GESELL",
    "2257": "MAR DE AJO",
    "2261": "LOBERIA",
    "2262": "NECOCHEA",
    "2264": "LA DULCE",
    "2265": "CORONEL VIDAL",
    "2266": "BALCARCE",
    "2267": "GENERAL MADARIAGA",
    "2268": "MAIPU (PROV.  BUENOS AIRES)",
    "2271": "MONTE",
    "2272": "NAVARRO",
    "2273": "CARMEN DE ARECO",
    "2274": "CARLOS SPEGAZZINI",
    "2281": "AZUL",
    "2283": "TAPALQUE",
    "2284": "OLAVARRIA",
    "2285": "LAPRIDA",
    "2286": "GENERAL LAMADRID",
    "2291": "MIRAMAR (PROV.  BUENOS AIRES)",
    "2292": "BENITO JUAREZ",
    "2296": "AYACUCHO",
    "2297": "RAUCH",
    "2302": "GENERAL PICO",
    "2314": "BOLIVAR",
    "2316": "DAIREAUX",
    "2317": "9 DE JULIO (PROV.  BUENOS AIRES)",
    "2320": "JOSE C. PAZ",
    "2323": "LUJAN (PROV.  BUENOS AIRES)",
    "2324": "MERCEDES (PROV.  BUENOS AIRES)",
    "2325": "SAN ANDRES DE GILES",
    "2326": "SAN ANTONIO DE ARECO",
    "2331": "REALICO",
    "2333": "QUEMU QUEMU",
    "2334": "EDUARDO CASTEX",
    "2335": "CALEUFU",
    "2336": "HUINCA RENANCO",
    "2337": "AMERICA",
    "2338": "VICTORICA",
    "2342": "BRAGADO",
    "2343": "NORBERTO DE LA RIESTRA",
    "2344": "SALADILLO (PROV.  BUENOS AIRES)",
    "2345": "25 DE MAYO (PROV.  BUENOS AIRES)",
    "2346": "CHIVILCOY",
    "2352": "CHACABUCO",
    "2353": "GENERAL ARENALES",
    "2354": "VEDIA",
    "2355": "LINCOLN",
    "2356": "GENERAL PINTO",
    "2357": "CARLOS TEJEDOR",
    "2358": "LOS TOLDOS (PROV.  BUENOS AIRES)",
    "2392": "TRENQUE LAUQUEN",
    "2393": "SALAZAR",
    "2394": "TRES LOMAS",
    "2395": "CARLOS CASARES",
    "2396": "PEHUAJO",
    "2473": "COLON (PROV.  BUENOS AIRES)",
    "2474": "SALTO",
    "2475": "ROJAS",
    "2477": "PERGAMINO",
    "2478": "ARRECIFES",
};

export interface ValidatePhoneResult {
    isValid: boolean;
    message: string;
    area: string;
    number: string;
}

export const validatePhone = (area: string, number: string): ValidatePhoneResult => {
    const areaStartWithZero = area.startsWith("0");
    const invalidChars = ["+", "-", " ", "(", ")"];

    if (areaStartWithZero) {
        return {
            isValid: false,
            message: "El código de área no puede comenzar con 0.",
            area: area,
            number: number,
        };
    }

    const areaHasInvalidChars = invalidChars.some((char) => area.includes(char));
    const numberHasInvalidChars = invalidChars.some((char) => number.includes(char));

    if (areaHasInvalidChars) {
        return {
            isValid: false,
            message: "El código de área no puede contener '+' o '-' o espacios.",
            area: area,
            number: number,
        };
    }

    if (numberHasInvalidChars) {
        return {
            isValid: false,
            message: "El número de teléfono no puede contener '+' o '-' o espacios.",
            area: area,
            number: number,
        };
    }

    const validLength = 10 - area.length;

    if (number.length !== validLength) {
        return {
            isValid: false,
            message: `El número de teléfono debe tener ${validLength} dígitos.`,
            area: area,
            number: number,
        };
    }

    const areHasOnlyNumbers = area.match(/^[0-9]+$/);
    const numberHasOnlyNumbers = number.match(/^[0-9]+$/);

    if (!areHasOnlyNumbers || !numberHasOnlyNumbers) {
        return {
            isValid: false,
            message: "El código de área y el número de teléfono deben ser numéricos.",
            area: area,
            number: number,
        };
    }

    const areaHasInAreaCodes = areaCodes[area] !== undefined;
    const areaName = areaCodes[area];

    if (!areaHasInAreaCodes) {
        return {
            isValid: false,
            message: "El código de área no es valido.",
            area: area,
            number: number,
        };
    }

    return {
        isValid: true,
        message: `Teléfono válido para ${areaName}`,
        area: area,
        number: number,
    };
};

export interface AreaCodeSearchResult {
    code: string;
    description: string;
}

export const removeLeadingZeros = (value: string): string => {
    return value.replace(/^0+/, "");
};

export const sanitizePhoneNumber = (value: string): string => {
    return value.replace(/\D/g, "");
};

export const sanitizeAreaCode = (value: string): string => {
    return removeLeadingZeros(sanitizePhoneNumber(value));
};

export const searchAreaCodes = (query: string | number): AreaCodeSearchResult[] => {
    let searchTerm = query.toString().toLowerCase();

    // Remove leading zeros if any
    searchTerm = removeLeadingZeros(searchTerm);

    const results: AreaCodeSearchResult[] = [];

    for (const [code, description] of Object.entries(areaCodes)) {
        if (code.includes(searchTerm) || description.toLowerCase().includes(searchTerm)) {
            results.push({ code, description });
        }
    }

    return results;
};
