import re
import json
import time
import urllib.parse
import json
import psycopg2
import requests
from LoggingFormatter import logger
import topfloatdb


def getWebshareProxies() -> list:
    try:
        dl_token = requests.get(
            "https://proxy.webshare.io/api/v2/proxy/config/",
            headers={"Authorization": "wsvwkkpdl6e2zirlyimm1nbkxbrcxf0zr07myh61"},
            timeout=10,
        ).json()["proxy_list_download_token"]

        proxy_list = requests.get(
            "https://proxy.webshare.io/api/v2/proxy/list/download/"
            + str(dl_token)
            + "/-/any/username/direct/",
            timeout=20,
        ).text
    except Exception as e:
        logger.error(str(e))
        return []

    all_proxies = []

    proxies = proxy_list.splitlines()
    for proxy in proxies:
        host = proxy.split(":")[0]
        port = proxy.split(":")[1]
        username = proxy.split(":")[2]
        password = proxy.split(":")[3]
        final_proxy = "http://" + username + ":" + password + "@" + host + ":" + port
        all_proxies.append(final_proxy)

    return all_proxies


def checkIfSkinExcluded(skin_name_with_condition):
    with open("excluded_skins.txt", "r") as f:
        if skin_name_with_condition in f.read():
            return True
        else:
            return False


def buildListingInfoList(listing_info, high_low):

    if "market_actions" not in listing_info["asset"]:
        # return None
        #'steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20M%listingid%A%assetid%D11970825653767741333'
        m_param = str(listing_info["listingid"])
        a_param = str(listing_info["asset"]["id"])
        d_param = ""
        full_inspect_link = "steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20M%listingid%A%assetid%D0"
    else:
        m_param = str(listing_info["listingid"])
        a_param = listing_info["asset"]["id"]
        full_inspect_link = listing_info["asset"]["market_actions"][0]["link"]
    spliced_inspect_link = str(full_inspect_link).split("%")
    d_param = str(spliced_inspect_link[-1])[1:]
    final_inspect_link = (
        "steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20M"
        + str(m_param)
        + "A"
        + str(a_param)
        + "D"
        + str(d_param)
    )

    if "converted_price" in listing_info:
        price = float(listing_info["converted_price"]) / 100
        fee = float(listing_info["converted_fee"]) / 100

    else:
        price = float(listing_info["price"]) / 100
        fee = float(listing_info["fee"]) / 100

    full_price = price + fee
    full_price = round(full_price, 2)

    return {
        "link": final_inspect_link,
        "m": m_param,
        "a": a_param,
        "d": d_param,
        "price": full_price,
        "high_low": high_low,
    }


def getSplittedBulkList(splitted_bulk):
    bulk_inspect_links_list = [{"links": []}]
    for i in splitted_bulk:
        # self.listings_info_dict[listing_to_check["m"]]["price"]
        try:
            bulk_inspect_links_list[0]["links"].append(
                {"link": list(i.values())[0]["link"]}
            )
        except Exception as e:
            try:
                logger.error(str(splitted_bulk))
                logger.error(str(list(i.values())))
                logger.error(str(bulk_inspect_links_list))
                logger.error("getSplittedBulkList():" + str(e))
                continue
            except Exception as e:
                logger.error("EXCEPT HELL: " + str(e))
                continue
    return bulk_inspect_links_list[0]


def floatidNotInBulk(single_inspect_server_url, bulk_at_j, request_manager):
    end_floatid = False
    counter_floatid = 0
    counter_exec = 0
    while not end_floatid:
        time.sleep(2)
        try:
            r_json = request_manager.getRequestNaked(single_inspect_server_url).json()
        except:
            continue
        counter_floatid += 1
        if "iteminfo" in r_json:
            if "floatid" in r_json["iteminfo"]:
                end_floatid = True
                return r_json["iteminfo"]

        else:
            logger.error(
                "iteminfo not in r_json with single_inspect_server_url: "
                + str(single_inspect_server_url)
            )
            continue

        if counter_floatid > 4:
            postgresql_conn = psycopg2.connect(
                database="postgres",
                user="postgres",
                password="Berufsorientierung1!",
                host="23.88.122.57",
                port="6432",
            )
            postgresql_cur = postgresql_conn.cursor()
            if "itemid" in bulk_at_j:
                postgresql_cur.execute(
                    "SELECT floatid FROM history WHERE a = %s", (bulk_at_j["itemid"],)
                )
            else:
                postgresql_cur.execute(
                    "SELECT floatid FROM history WHERE a = %s", (bulk_at_j["a"],)
                )
            try:
                floatid = postgresql_cur.fetchone()[0]
            except TypeError:
                end_floatid = True
                logger.error(
                    "FLOATID NOT IN AFTER 5 TRIES, GIVING UP WITH "
                    + str(single_inspect_server_url)
                )
                continue

            postgresql_cur = postgresql_conn.cursor()
            postgresql_cur.execute("DELETE FROM items WHERE floatid = %s", (floatid,))
            postgresql_conn.commit()

            counter_exec += 1
            if counter_exec > 4:
                end_floatid = True
                logger.error(
                    "EXECUTED DB QUERY MULTIPLE TIMES, SKIPPING - "
                    + str(single_inspect_server_url)
                )
            continue

def floatIdNotInSingle(single_inspect_link):
    end = False
    counter_floatid = 0
    while not end:
        counter_floatid += 1
        if counter_floatid > 6:
            logger.error("FLOATID NOT IN AFTER 5 TRIES, GIVING UP WITH " + str(single_inspect_link))
            return None
        time.sleep(1 + counter_floatid)
        try:
            r_json = requests.get("http://23.88.122.57:1337/?url=" + str(single_inspect_link)).json()
        except:
            continue
        if "iteminfo" in r_json:
            if "floatid" in r_json["iteminfo"]:
                #logger.error("FLOATID FOUND AFTER " + str(counter_floatid) + " TRIES FOR " + str(single_inspect_link))
                return r_json["iteminfo"]
            else:
                if "m" in r_json["iteminfo"]:
                    with topfloatdb.db_cursor() as cur:
                        cur.execute(
                            "UPDATE items SET floatid = %s WHERE ms = %s AND paintindex = %s",
                            (r_json["iteminfo"]["a"], r_json["iteminfo"]["m"], r_json["iteminfo"]["paintindex"],),
                        )
                elif "s" in r_json["iteminfo"] and "s" != "0":
                    with topfloatdb.db_cursor() as cur:
                        cur.execute(
                            "UPDATE items SET floatid = %s WHERE ms = %s AND paintindex = %s",
                            (r_json["iteminfo"]["a"], r_json["iteminfo"]["s"], r_json["iteminfo"]["paintindex"],),
                        )
                else:
                    logger.critical("WTF IS GOING ON??????????" + str(r_json))

def retryBulkError(new_splitted_bulk, j):
    repeat_counter = 0
    end = False
    for links in new_splitted_bulk["links"]:
        if end is True:
            break
        link = links["link"]
        all_params = getParamsFromInspectLink(link)
        a_param = all_params[1]
        if str(j == str(a_param)):
            inspect_link = generateInspectLink(all_params[0], "0", all_params[1], all_params[2])

            while not end:
                repeat_counter += 1
                if repeat_counter > 6:
                    logger.error("RETRYING BULK ERROR FAILED 5 TIMES FOR " + str(inspect_link))
                    end = True
                r_json = requests.get("http://23.88.122.57:1337/?url=" + str(inspect_link)).json()
                if "error" in r_json:
                    time.sleep(1)
                    continue
                else:
                    if "iteminfo" in r_json:
                        return r_json["iteminfo"]
                    else:
                        time.sleep(1)
                        continue
        else:
            continue
    return None

def getParamsFromInspectLink(inspect_link):
    try:
        params_only = str(inspect_link).split("%20")[1]
        m_param = params_only.split("A")[0][1:]
        a_param = params_only.split("D")[0].split("A")[1]
        d_param = params_only.split("D")[1]
    except Exception as e:
        logger.error(str(e))
        return None
    return [m_param, a_param, d_param]

def encodeItemName(full_item_name):
    item_encoded = urllib.parse.quote(full_item_name)
    item_encoded = item_encoded.replace("%28", "(")
    item_encoded = item_encoded.replace("%29", ")")
    return item_encoded


def encodeAidsItemName(full_item_name):
    item_encoded = urllib.parse.quote(full_item_name)
    item_encoded = item_encoded.replace("%28", "(")
    item_encoded = item_encoded.replace("%29", ")")
    item_encoded = item_encoded.replace("|", "%7C")
    item_encoded = item_encoded.replace("&", "%26")
    # Souvenir%20P250%20|%20Black%20&%20Tan%20(Battle-Scarred)
    return item_encoded


def generateMarketLink(item_encoded, m, a):
    market_link = (
        "https://steamcommunity.com/market/listings/730/"
        + str(item_encoded)
        + "#buylisting|"
        + str(m)
        + "|730|2|"
        + str(a)
    )
    return market_link


def generateInspectLink(m, s, a, d):
    # steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20M1528254914329764554A7340413D12442007912786617073
    if str(m) != "0":
        inspect_link = (
            "steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20M"
            + str(m)
            + "A"
            + str(a)
            + "D"
            + str(d)
        )
    else:
        inspect_link = (
            "steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20M"
            + str(s)
            + "A"
            + str(a)
            + "D"
            + str(d)
        )

    return inspect_link


def writeSingleAnyToFile(single_dict, filename):
    f_cheap = open(str(filename), "a", encoding="utf-8")
    f_cheap.write(json.dumps(single_dict, indent=4))
    f_cheap.write(",")
    f_cheap.close()


def writeSingleCheapSkinToFile(single_cheap_top_dict):
    f_cheap = open("cheap_top_skins.txt", "a", encoding="utf-8")
    f_cheap.write(json.dumps(single_cheap_top_dict, indent=4))
    f_cheap.write(",")
    f_cheap.close()


def manuallyGetNameIDURL(listing_source_page):
    x = re.search(r"Market_LoadOrderSpread\( [0-9]+ \)", listing_source_page)
    if x is not None:
        aids = x.group()
        nameid = re.sub(r"\D", "", str(aids))
        if nameid is None:
            return None
        else:
            return (
                "https://steamcommunity.com/market/itemordershistogram?country=FR&language=german&currency=3&item_nameid="
                + nameid
            )
    else:
        return None
