import re
import json
from datetime import datetime
import time
import urllib.parse
import json
import psycopg2
import requests

def getWebshareProxies(all_sessions: list) -> list:
    ip_addresses = []

    response = requests.get(
        "https://proxy.webshare.io/api/v2/proxy/list/download/hdaovifqwgapnzijunmiptygnyrtyqaeyvvvqgdo/-/any/username/direct/"
    )
    splitted = response.text.rsplit("\n")
    for ip in splitted:
        clean_ip = ip.replace("\r", "")
        splitted_ip = clean_ip.split(":")
        if splitted_ip[0] != "":
            full_ip = (
                "http://"
                + splitted_ip[2]
                + ":"
                + splitted_ip[3]
                + "@"
                + splitted_ip[0]
                + ":"
                + splitted_ip[1]
            )
            ip_addresses.append(full_ip)

    return ip_addresses

def insertShittyRankSupaBase(inspect_link, rank):
    try:
        postgresql_conn = psycopg2.connect(
            database="postgres",
            user="postgres",
            password="Berufsorientierung1!",
            host="23.88.122.57",
            port="5432",
        )
        postgresql_cur = postgresql_conn.cursor()
        postgresql_cur.execute(
            "INSERT INTO floats(inspect_link, rank) VALUES(%s, %s)",
            (
                inspect_link,
                rank,
            ),
        )
        postgresql_conn.commit()
        postgresql_cur.close()
    except (Exception, psycopg2.DatabaseError) as error:
        writeErrorToLog("insertShittyRankSupaBase(): " + str(error))
    finally:
        if postgresql_conn is not None:
            postgresql_conn.close()


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:
            writeErrorToLog(
                "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="5432",
            )
            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
                writeErrorToLog(
                    "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
                writeErrorToLog(
                    "EXECUTED DB QUERY MULTIPLE TIMES, SKIPPING - "
                    + str(single_inspect_server_url)
                )
            continue


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 buildListParams(
    listings_page_json, temp_list, temp_list_entry, inspect_link_only=True
):
    m_param = str(temp_list[temp_list_entry])
    a_param = listings_page_json["listinginfo"][m_param]["asset"]["id"]
    if "market_actions" not in listings_page_json["listinginfo"][m_param]["asset"]:
        return None
    full_inspect_link = listings_page_json["listinginfo"][m_param]["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 listings_page_json["listinginfo"][m_param]:
        price = (
            float(listings_page_json["listinginfo"][m_param]["converted_price"]) / 100
        )
        fee = float(listings_page_json["listinginfo"][m_param]["converted_fee"]) / 100

    else:
        price = float(listings_page_json["listinginfo"][m_param]["price"]) / 100
        fee = float(listings_page_json["listinginfo"][m_param]["fee"]) / 100

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

    if inspect_link_only is True:
        return {"link": final_inspect_link}
    else:
        return {
            "link": final_inspect_link,
            "m": m_param,
            "a": a_param,
            "d": d_param,
            "price": full_price,
        }


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:
                writeErrorToLog(str(splitted_bulk))
                writeErrorToLog(str(list(i.values())))
                writeErrorToLog(str(bulk_inspect_links_list))
                writeErrorToLog("getSplittedBulkList():" + str(e))
                continue
            except Exception as e:
                writeErrorToLog("EXCEPT HELL: " + str(e))
                continue
    return bulk_inspect_links_list[0]


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 getPrice(listings_info_list, bulk_response_json_on_j):
    price = None
    for i in listings_info_list:
        if i["m"] == bulk_response_json_on_j["m"]:
            price = i["price"]
            return price
    if price == None:
        writeErrorToLog("NO PRICE WITH: " + str(bulk_response_json_on_j))
        return 0


def getRealInspectLink(listings_info_list, bulk_response_json_on_j):
    inspect_link = None
    for i in listings_info_list:
        if i["m"] == bulk_response_json_on_j["m"]:
            inspect_link = i["link"]
            return inspect_link
    if inspect_link == None:
        writeErrorToLog("NO INSPECT LINK WITH: " + str(bulk_response_json_on_j))
        return None


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 returnMorSfromInspectLink(inspect_link):
    m_s = str(inspect_link).split("%20")[1].split("A")[0]
    return m_s


def manuallyGetNameIDURL(listing_source_page):
    x = re.search("Market_LoadOrderSpread\( [0-9]+ \)", listing_source_page)
    if x is not None:
        aids = x.group()
        nameid = re.sub("\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


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 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 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 writeErrorToLog(error):
    now = datetime.now()
    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
    f = open("errors.txt", "a", encoding="utf-8")
    f.write(str(dt_string) + ": " + str(error))
    f.write("\n")
    f.close()
    time.sleep(0.5)


def writeAnythingToAnyFile(filename, log):
    f = open(str(filename), "a", encoding="utf-8")
    f.write(str(log) + "\n")
    f.close()
