import json
import requests
import os
import re


def fetchJson(apiUrl):
    headers = {
        "User-Agent": "NeuRepo"
    }
    try:
        response = requests.get(apiUrl, headers=headers)
        response.raise_for_status()
        text = response.text.strip()
        if text.startswith("/**/(") and text.endswith(")"):
            text = text[5:-1]
        return json.loads(text)
    except requests.RequestException as e:
        raise requests.RequestException(f"Error fetching data from {apiUrl}: {e}")
    except json.JSONDecodeError as e:
        raise ValueError(f"Error decoding JSON: {e}")


RARITIES = ["Common", "Uncommon", "Rare", "Epic", "Legendary", "Mythic"]

defaultPattern = re.compile(
    r'{{!}} style="text-align: left" {{!}} {{Pet/(?P<PetId>[A-Z_]+)}} ?\n'
    r'{{!}} ?(?:{{Coins\|(?P<PriceCommon>[0-9,]+)\|No}})? ?\n'
    r'{{!}} ?(?:{{Coins\|(?P<PriceUncommon>[0-9,]+)\|No}})? ?\n'
    r'{{!}} ?(?:{{Coins\|(?P<PriceRare>[0-9,]+)\|No}})? ?\n'
    r'{{!}} ?(?:{{Coins\|(?P<PriceEpic>[0-9,]+)\|No}})? ?\n'
    r'{{!}} ?(?:{{Coins\|(?P<PriceLegendary>[0-9,]+)\|No}})? ?\n'
    r'{{!}} ?(?:{{Coins\|(?P<PriceMythic>[0-9,]+)\|No}})? ?\n',
    re.MULTILINE
)

alternatePattern = re.compile(
    r'{{!}} style="text-align: left" {{!}} {{Image\|.+}} \[\[(?P<PetId>.+) Pet]] ?\n'
    r'{{!}} ?(?:{{Coins\|(?P<PriceCommon>[0-9,]+)\|No}})? ?\n'
    r'{{!}} ?(?:{{Coins\|(?P<PriceUncommon>[0-9,]+)\|No}})? ?\n'
    r'{{!}} ?(?:{{Coins\|(?P<PriceRare>[0-9,]+)\|No}})? ?\n'
    r'{{!}} ?(?:{{Coins\|(?P<PriceEpic>[0-9,]+)\|No}})? ?\n'
    r'{{!}} ?(?:{{Coins\|(?P<PriceLegendary>[0-9,]+)\|No}})? ?\n'
    r'{{!}} ?(?:{{Coins\|(?P<PriceMythic>[0-9,]+)\|No}})? ?\n',
    re.MULTILINE
)


def processMatch(match, result):
    pet_id = match.group("PetId").upper().replace(" ", "_")
    for index, rarity in enumerate(RARITIES):
        val = match.group(f"Price{rarity}")
        key = f"{pet_id};{index}"

        adjusted_key = petNameOverrides.get(key, key)

        if val:
            price = int(val.replace(",", ""))
            if price == 0:
                continue
            result[adjusted_key] = price


def processWikiText(text):
    result = {}
    for match in defaultPattern.finditer(text):
        processMatch(match, result)

    for match in alternatePattern.finditer(text):
        processMatch(match, result)

    addOverrides(result)

    return result


# Manually set prices for pets that are missing or incorrect on the wiki
petPriceOverrides = {
    "RIFT_FERRET;3": 50_000,
    "RIFT_FERRET;4": 50_000,
    "SNOWMAN;5": 2_000_000,
}

petNameOverrides = {
    "WISP;1": "DROPLET_WISP;1",
    "WISP;2": "FROST_WISP;2",
    "WISP;3": "GLACIAL_WISP;3",
    "WISP;4": "SUBZERO_WISP;4",
}


def addOverrides(result):
    for key, value in petPriceOverrides.items():
        result[key] = value


if __name__ == '__main__':
    url = "https://wiki.hypixel.net/api.php?action=query&format=json&prop=revisions&titles=Template:George_List&callback=&rvprop=content&rvslots=main"
    raw = fetchJson(url)
    pages = raw["query"]["pages"]
    page = next(iter(pages.values()))
    wikitext = page["revisions"][0]["slots"]["main"]["*"]
    petPrices = processWikiText(wikitext)
    outputJson = {
        "notice": "This file is automatically generated and should not be modified manually. Please edit the `updateGeorgePrices.py` file instead.",
        "prices": petPrices
    }

    os.makedirs(os.path.dirname("constants/george.json"), exist_ok=True)
    with open("constants/george.json", "w") as json_file:
        json.dump(outputJson, json_file, indent=2, sort_keys=True)

    print(f"Saved {len(petPrices)} pet prices to george.json")
