import urllib.parse
import requests

# Same descriptive User-Agent rule as every other
# Wikimedia call in this book — see Section 3.4.
HEADERS = {"User-Agent": "GLAMWalkTeachingExample/1.0 (https://soretruth.com; teaching example)"}


def normalize_commons_url(raw_value, width=None):
    """
    Take whatever form a Commons image reference arrives in, and
    return a URL that reliably loads the actual image bytes.

    Some Commons originals (museum scans especially) are tens of
    thousands of pixels on a side and hundreds of megabytes — well
    past what a browser or image library will decode. Pass `width`
    to get a Commons-generated thumbnail at that width instead of
    the raw original; Special:FilePath accepts a `width` query
    param and redirects to the matching thumbnail. Leave it None
    when you actually want the full-resolution file.
    """
    raw_value = raw_value.strip()

    # Already a full, direct upload.wikimedia.org URL — leave it alone.
    # (No width param support here since this is already a resolved,
    # concrete file URL rather than a Special:FilePath redirect.)
    if raw_value.startswith("https://upload.wikimedia.org/"):
        return raw_value

    # A Special:FilePath link, or a bare filename — both resolve
    # correctly through the Special:FilePath redirect, which is
    # Commons' own stable, documented way to ask "give me the file
    # this name refers to, whatever its real storage path is."
    if raw_value.startswith("https://commons.wikimedia.org/wiki/Special:FilePath/"):
        url = raw_value
    else:
        filename = raw_value.split("/")[-1]  # strip any URL scaffolding down to just the filename
        filename = urllib.parse.quote(filename)  # escape spaces and special characters safely
        url = f"https://commons.wikimedia.org/wiki/Special:FilePath/{filename}"

    if width:
        url += f"?width={width}"
    return url


def get_wikidata_image_filename(qid):
    """
    Look up the Commons filename a Wikidata item
    currently has on record via its P18 (image) claim,
    instead of typing a filename from memory.

    qid is a Wikidata item ID, e.g. "Q45585".
    """
    url = "https://www.wikidata.org/w/api.php"
    params = {
        "action": "wbgetclaims",
        "property": "P18",
        "entity": qid,
        "format": "json",
    }
    response = requests.get(url, params=params, headers=HEADERS, timeout=15)
    response.raise_for_status()
    data = response.json()

    claims = data.get("claims", {}).get("P18", [])
    if not claims:
        return None

    return claims[0]["mainsnak"]["datavalue"]["value"]


if __name__ == "__main__":

    print("--- Part 1: normalize_commons_url() on all three input shapes ---")
    bare_filename = "Tour Eiffel, Paris.JPG"
    full_upload_url = "https://upload.wikimedia.org/wikipedia/commons/2/25/Tour_Eiffel%2C_Paris.JPG"
    filepath_url = "https://commons.wikimedia.org/wiki/Special:FilePath/Tour_Eiffel,_Paris.JPG"

    for label, raw in (
        ("bare filename", bare_filename),
        ("full upload.wikimedia.org URL", full_upload_url),
        ("Special:FilePath URL", filepath_url),
    ):
        print(f"{label}: {normalize_commons_url(raw)}")

    print()
    print("--- Part 2: the naive guess vs. the resolved lookup ---")

    naive_guess = "Starry_Night.jpg"
    print(f"Naive guess: {naive_guess}")
    print(f"Naive result: {normalize_commons_url(naive_guess)}")
    print("(loads with no error — and is NOT Van Gogh's painting)")

    print()
    # Q45585 is Wikidata's item for The Starry Night.
    resolved_filename = get_wikidata_image_filename("Q45585")
    print(f"Resolved filename (from Wikidata): {resolved_filename}")
    print(f"Full-res result: {normalize_commons_url(resolved_filename)}")
    print("(this IS the actual painting — but it's a 44,567 x 35,291px,")
    print(" ~664MB Google Art Project scan, past what most browsers will")
    print(" decode, so it can look 'broken' even though it's correct)")
    print(f"Browser-safe thumbnail: {normalize_commons_url(resolved_filename, width=1024)}")