import json
from datetime import datetime
import time
import urllib.parse
import json
from datetime import datetime
import os
import sys
import socket

# ???????????????????????????????????????????
# sys.path.append(os.path.abspath("/var/www/cs2snipeproduction/cs2snipe"))
# os.environ["DJANGO_SETTINGS_MODULE"] = "cs2snipe.settings"
# #os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cs2snipe.settings')
# import django

# django.setup()
# from sniper.models import cs2snipe_queries
# from sniper.models import cs2snipe_found
# from sniper.models import cs2snipe_users
# from django.utils import timezone
import requests
from RequestManager import RequestManager

# {'weapon_name': 'tag_weapon_knife_flip', 'skin_or_weapon': 'weapon', 'stat': 'stat_only', 'filter_options': 'other_filter', 'condition': 'Factory New', 'more_filters': ['rank'], 'rank': 1, 'pages': 2, 'question1': ['Item 1']}
# {'weapon_name': 'tag_weapon_ak47', 'skin_or_weapon': 'weapon', 'stat': 'stat_and_non_stat', 'filter_options': 'exact_float', 'exact_float': 0.499945, 'more_filters': ['rank', 'pattern', 'price'], 'rank': 1, 'pattern': 2, 'price': 3, 'pages': 4, 'question1': ['Item 1']}

# {'weapon_name': 'tag_weapon_famas', 'skin_or_weapon': 'weapon', 'stat': 'stat_only', 'filter_options': 'float_restrictions', 'float_restrictions': 'starts_with', 'float_for_restriction': 0.1, 'more_filters': ['rank'], 'rank': 1, 'pages': 1, 'question1': ['Item 1']}
# {'weapon_name': 'tag_weapon_knife_flip', 'skin_or_weapon': 'weapon', 'stat': 'stat_and_non_stat', 'filter_options': 'float_restrictions', 'float_restrictions': 'is_bigger', 'float_for_restriction': 0.1, 'more_filters': ['price'], 'price': 1, 'pages': 1, 'question1': ['Item 1']}
# {'weapon_name': 'tag_weapon_knife_falchion', 'skin_or_weapon': 'weapon', 'stat': 'stat_and_non_stat', 'filter_options': 'float_restrictions', 'float_restrictions': 'is_smaller', 'float_for_restriction': 0.1, 'more_filters': ['rank'], 'rank': 1, 'pages': 2, 'question1': ['Item 1']}

# {'weapon_name': 'tag_weapon_galilar', 'skin_or_weapon': 'weapon', 'stat': 'stat_only', 'filter_options': 'other_filter', 'more_filters': ['rank', 'pattern', 'price'], 'condition': 'Battle-Scarred', 'rank': 1, 'pattern': 2, 'price': 3, 'pages': 1, 'question1': ['Item 1']}

# {'skin_or_weapon': 'skin', 'stat': 'stat_only', 'skin_name': 'AK-47 | Nighwish', 'filter_options': 'other_filter', 'condition': 'Factory New', 'more_filters': ['rank'], 'rank': 1, 'pages': 2, 'question1': ['Item 1']}

def singleBuildInspectList(result_json, listing, ReqManager):
    listing_info_list = []
    pages = result_json["pages"]
    count = 100
    # for listing in weapon_listings_url_list:
    # print("AT LISTING " + str(listing))
    last_page = False
    for page in range(pages):
        # print(str(page))
        if last_page is True:
            break
        end = False
        # print(str(last_page))
        repeat_counter = 0
        while not end:
            start = page * 100
            repeat_counter += 1
            if repeat_counter > 10:
                end = True
            single_listings_url = (
                str(listing)
                + "&start="
                + str(start)
                + "&count="
                + str(count)
                + "&currency=3"
            )
            # print(single_listings_url)


            get_alternator = 1
            get_counter = 0
            while True:
                get_alternator = (get_alternator + 1) % 3
                get_counter += 1
                if get_counter > 20:
                    print("Couldn't get page for 20 times: " + str(single_listings_url))
                    return []
                response = ReqManager.getRequest(single_listings_url, get_alternator)
                response_json = validateResponseInspectList(response=response)
                if response_json is None:
                    print("Response Validation failed, trying again.")
                    time.sleep(1)
                    continue

                break

            no_more_pages = noMorePages(response_json=response_json)

            if no_more_pages is None:
                print("Response Validation failed, trying again.")
                time.sleep(1)
                continue

            if no_more_pages is True:
                # end = True
                last_page = True
                print("This was the last page, will end now.")
                print(response_json["start"])
                print(response_json["total_count"])

            if len(response_json["listinginfo"]) > 0:
                for listing_id in response_json["listinginfo"].keys():
                    listing_info = response_json["listinginfo"][str(listing_id)]
                    all_params = buildListingInfoList(listing_info=listing_info, page=page)
                    listing_info_list.append(all_params)
            end = True
    return listing_info_list

def bulkAction(inspect_link_list):
    bulk_inspect_link_list = [{"links": []}]
    splitted_list_index = 0
    inspect_link_counter = 0
    for inspect_link in inspect_link_list:
        if inspect_link_counter > 99:
            splitted_list_index += 1
            bulk_inspect_link_list.append({"links": []})
            inspect_link_counter = 0
        try:
            bulk_inspect_link_list[splitted_list_index]["links"].append(
                {"link": list(inspect_link.values())[0]}
            )
            inspect_link_counter += 1
        except Exception as e:
            print(inspect_link_list)
            print(str(e))
            continue
    return bulk_inspect_link_list


def validateSkinportSearch(response: requests.Response):
    if response is None:
        return False
    try:
        response_json = response.json()
    except Exception as e:
        print(str(e))
        return False
    if "data" not in response_json:
        return False
    if len(response_json["data"]) == 0:
        return False

    return response_json


def validateResponseHashedNameList(response: requests.Response):
    if response is None:
        return None
    try:
        response_json = response.json()
    except Exception as e:
        print(str(e))
        return None
    if response_json is None:
        return None
    if "total_count" in response_json:
        if response_json["total_count"] == 0:
            return None
    if "results" in response_json:
        if len(response_json["results"]) == 0:
            return None
    return response_json


def noMorePages(response_json: str):
    # if response_json["total_count"] == response_json["start"]:
    #     return True
    
    if "total_count" in response_json and "start" in response_json:
        if int(response_json["start"]) + 100 >= response_json["total_count"]:
            return True
        else:
            return False
    else:
        return None


def validateResponseInspectList(response: requests.Response):
    if response is None:
        return None
    if response.text == "null":
        return None
    try:
        response_json = response.json()
        # print(response_json)
    except Exception as e:
        print(str(e))
        return None
    if response_json is None:
        return None
    
    if response_json["total_count"] == response_json["pagesize"]:
        return response_json

    if "success" in response_json:
        if response_json["success"] is False or response_json["success"] == "false":
            return None

    if "total_count" in response_json:
        if response_json["total_count"] == 0:
            if safetyCheckStock(response):
                return None
            else:
                #???????????
                return response_json

    if "listinginfo" not in response_json:
        return None
    if len(response_json["listinginfo"]) == 0:
        return None

    return response_json

#https://api.skinscout.net/api/items?name=%E2%98%85%20Bayonet%20%7C%20Rust%20Coat&exterior=StatTrak-Well-Worn
#https://api.skinscout.net/api/items?name=%E2%98%85%20Gut%20Knife%20%7C%20Rust%20Coat&exterior=StatTrak-Well-Worn
def safetyCheckStock(response: requests.Response):
    try:
        full_name = str(response.url).split("/")[0:-2][-1]
        if full_name.startswith("StatTrak"):
            market_hash_name = full_name.split("StatTrak%E2%84%A2%20")[1]
            exterior = "StatTrak-" + str(market_hash_name.split("%28")[1].split("%29")[0])
            name_only = full_name.split("StatTrak%E2%84%A2%20")[1].split("%20%28")[0]
        elif full_name.startswith("Souvenir"):
            market_hash_name = full_name.split("Souvenir%20")[1]
            exterior = "Souvenir-" + str(market_hash_name.split("%28")[1].split("%29")[0])
            name_only = full_name.split("Souvenir%20")[1].split("%20%28")[0]
        elif full_name.startswith("%E2%98%85%20StatTrak%E2%84%A2%20"):
            name_only = str(full_name.split("%20%28")[0]).replace("StatTrak%E2%84%A2%20", "")
            exterior = "StatTrak-" + str(full_name.split("%28")[1].split("%29")[0])
        elif full_name.startswith("%E2%98%85%20"):
            name_only = full_name.split("%20%28")[0]
            exterior = full_name.split("%28")[1].split("%29")[0]
        else:
            exterior = full_name.split("%28")[1].split("%29")[0]
            name_only = full_name.split("%20%28")[0]
        url = "https://api.skinscout.net/api/items?name=" + str(name_only) + "&exterior=" + str(exterior)
        req = RequestManager()
        r = req.getRequestNaked(url=url).json()
        if len(r["item"]["item_selected"]["market_data"]) == 0:
            return False
        if r["item"]["item_selected"]["market_data"][0]["marketplace"]["name"] == "Steam":
            if "stock" not in r["item"]["item_selected"]["market_data"][0]:
                return False
            stock = r["item"]["item_selected"]["market_data"][0]["stock"]
            if stock > 0:
                return True
        return False
    except Exception as e:
        print(str(e))
        print("AUAUAUAUAUU SORRY FÜR MÜLLSCHEIß")

def buildListingInfoList(listing_info, page):
    m_param = str(listing_info["listingid"])
    a_param = listing_info["asset"]["id"]
    if "market_actions" not in listing_info["asset"]:
        return None
    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,
        "page": page,
        "price": full_price,
    }


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 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 getPage(listings_info_list, bulk_response_json_on_j):
    page = None
    for i in listings_info_list:
        if i["m"] == bulk_response_json_on_j["m"]:
            page = i["page"]
            return page
    if page == 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 isOpen(ip,port):
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   try:
      s.connect((ip, int(port)))
      s.shutdown(2)
      return True
   except:
      return False

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()
