from typing import Tuple
import requests


def _to_seloger_geographical_code(post_code: str) -> Tuple[str, str]:
    """
    Convert French 'Code Postal' to seloger's appropriate custom geographical code.

    Args:
        post_code: standard French post codes.

    Returns:
        - 'cp' or 'ci', the type of geographical code returned
        - the actual geographical code, in seloger's nomenclatura.

    Raises:
        ValueError if we don't get a match in seloger's database of codes.
        RuntimeError if we get more than two matches.
    """
    post_code = str(post_code)
    url = (
        f"https://autocomplete.svc.groupe-seloger.com/api/v2.0/auto/complete/fra"
        f"/63/10/8/SeLoger?text={post_code}"
    )
    response = requests.get(url)
    cities = response.json()

    matches = []
    for city in cities:
        if city.get("Type", None) == "Group":
            if post_code == str(city.get("Params", {}).get("cp", "")):
                matches = [("cp", post_code)]
                break
        if post_code in city.get("Meta", {}).get("Zips", []):
            matches.append(("ci", city["Params"]["ci"]))
            continue
        if post_code == str(city.get("Params", {}).get("cp", "")):
            matches.append(("cp", post_code))

    if not matches:
        msg = f"Unknown post code '{post_code}'."
        raise ValueError(msg)
    if len(matches) == 2:
        # for department that match large cities (e.g. Paris, Lyon) we can get 2 matches
        # One for the department and one for the group of arrondissements
        # we arbitrarily return the department code
        if set([geo_type for geo_type, geo_code in matches]) != {
            "cp",
            "ci",
        }:  # pragma: no cover
            msg = (
                f"Got multiple matches for post code '{post_code}'. "
                "This should never happen!"
            )
            raise RuntimeError(msg)
        matches = [match for match in matches if match[0] == "cp"]
    if len(matches) > 2:  # pragma: no cover
        msg = (
            f"Got multiple matches for post code '{post_code}'. "
            "This should never happen!"
        )
        raise RuntimeError(msg)

    return matches[0]