from time import sleep
import sqlite3
import xml.etree.ElementTree as ElementTree
import typer
import requests


base_url = "https://render.albiononline.com/v1/item/{uniquename}.png"

app = typer.Typer()

def load_xml(filename: str):
    tree = ElementTree.parse(filename)
    return tree

def filter_recipes(items):
    items_all = set()
    recipes = []
    a = items.findall("consumableitem")
    for item in a:
        un = item.attrib["uniquename"]
        if "UNIQUE" in un or "VANITY" in un:
            print(un)
            continue
        try:
            items_all.add(un)
            t = item.attrib["slottype"]
            for_item = []
            for child in item:
                if child.tag == "craftingrequirements":
                    am = child.attrib["amountcrafted"]
                    res = {r.attrib["uniquename"]: r.attrib["count"] for r in child}
                    items_all.update(res.keys())
                    for_item.append((am, res))
            recipes.append((un, t, for_item))
        except Exception as e:
            print(e, un)
    return items_all, recipes

def save_items(items_all, db):
    db.execute("DROP TABLE IF EXISTS item;")
    db.execute("CREATE TABLE item (uniquename STRING);")
    db.executemany("INSERT INTO item VALUES (?);", map(lambda x: (x,), items_all))

def save_recipes(recipes, db):
    db.execute("DROP TABLE IF EXISTS recipe;")
    db.execute("CREATE TABLE recipe (item INTEGER REFERENCES item(ROWID), amountcrafted INTEGER);")
    db.execute("DROP TABLE IF EXISTS ingredient;")
    db.execute("CREATE TABLE ingredient (recipe INTEGER REFERENCES recipe(ROWID), item INTEGER REFERENCES item(ROWID), amount INTEGER);")
    db = db.cursor()
    for un, t, for_item in recipes:
        for am, res in for_item:
            db.execute("INSERT INTO recipe VALUES ((SELECT ROWID FROM item WHERE uniquename=?), ?);", (un, am))
            i = db.lastrowid
            ingredients = map(lambda x: (i, x[0], x[1]), res.items())
            db.executemany("INSERT INTO ingredient VALUES (?, (SELECT ROWID FROM item WHERE uniquename=?), ?);", ingredients)

@app.command()
def extract_recipes(path_to_items_xml: str, output_filename: str):
    items = load_xml(path_to_items_xml)
    items_all, recipes = filter_recipes(items)
    with sqlite3.connect(output_filename) as db:
        save_items(items_all, db)
        save_recipes(recipes, db)

@app.command()
def download_images(path_to_db: str):
    with sqlite3.connect(path_to_db) as db:
        db.execute("DROP TABLE IF EXISTS image;")
        db.execute("CREATE TABLE image (item INTEGER REFERENCES item(ROWID), image BLOB);")
        for i, uniquename in db.execute("SELECT ROWID, uniquename FROM item;"):
            response = requests.get(base_url.format(uniquename=uniquename))
            if response.status_code != 200:
                print(uniquename)
                continue
            db.execute("INSERT INTO image VALUES (?, ?);", (i, response.content))
            sleep(1)

@app.command()
def extract_titles(path_to_localization_xml: str, path_to_db: str):
    with sqlite3.connect(path_to_db) as db:
        db.execute("DROP TABLE IF EXISTS title;")
        db.execute("CREATE TABLE title (item INTEGER REFERENCES item(ROWID), en STRING, ru STRING);")
        uns = dict(db.execute("SELECT uniquename, ROWID FROM item;").fetchall())
        tree = ElementTree.parse(path_to_localization_xml)
        ns = {"xml":"http://www.w3.org/XML/1998/namespace"}
        for tu in tree.findall("body/tu"):
            un = tu.attrib["tuid"].removeprefix("@ITEMS_")
            if un in uns:
                en = tu.find("tuv[@xml:lang='EN-US']/seg", ns).text
                ru = tu.find("tuv[@xml:lang='RU-RU']/seg", ns).text
                db.execute("INSERT INTO title VALUES (?, ?, ?);", (uns[un], en, ru))


if __name__ == "__main__":
    app()
