from api import BigApi


def containsAudioStrap(shopifyOrder):
    for lineItem in shopifyOrder["line_items"]:
        if lineItem["product_id"] == 8100195008729:
            if lineItem["fulfillment_status"] == None and lineItem["fulfillable_quantity"] == 1:
                return True
    return False

def containsBeyond(shopifyOrder):
    for lineItem in shopifyOrder["line_items"]:
        if lineItem["product_id"] == 7693929054425:
            if lineItem["fulfillment_status"] == None and lineItem["fulfillable_quantity"] == 1:
                return True
    return False

def containsRxLenses(shopifyOrder):
    for lineItem in shopifyOrder["line_items"]:
        if lineItem["product_id"] == 7761325916377:
            if lineItem["fulfillment_status"] == None and lineItem["fulfillable_quantity"] == 1:
                return True
    return False

def isValidOrder(shopifyOrder):
    if shopifyOrder["cancelled_at"] != None:
        return False
    if shopifyOrder["financial_status"] == "refunded" or shopifyOrder["financial_status"] == "partially_refunded":
        return False
    return True

def getBigOrderInventory(bigOrder):
    bigOrderID = bigOrder["id"]
    url = f"/admin/shop/order/{bigOrderID}/inventory"
    data = BigApi.adminGet(url)
    return data

def bigOrderRequirementState(bigOrder, inStockOnly = False):
    ## can be "hmdOnly", "hmdAndLenses", or "outOfScope"
    if bigOrder["state"] == "WaitingForScanRequest":
        return "outOfScope"
    if "shipmentHold" in bigOrder:
        return "outOfScope"
    inventory = getBigOrderInventory(bigOrder)
    # Perform inventory check on this order. If it is waiting on more than just the HMD, return false
    needLenses = False
    needOther = False
    for item in inventory:
        if item["productType"] != "BigscreenBeyondV1" and item["productType"] != "PrescriptionLensInserts" and item["productType"] == "PrescriptionLenses" and (item["status"] == "StockAvailable") == inStockOnly:
            needOther = True
        if (item["productType"] == "PrescriptionLensInserts" or item["productType"] == "PrescriptionLenses") and (item["status"] == "StockAvailable") == inStockOnly:
            needLenses = True
    
    if needOther:
        return "outOfScope"
    if needLenses:
        return "hmdAndLenses"
    return "hmdOnly"

def containsOneUnfulfilledItem(shopifyOrder):
    unfulfilledLineItems = 0
    for lineItem in shopifyOrder["line_items"]:
        if lineItem["fulfillment_status"] == None:
            unfulfilledLineItems += 1
    return unfulfilledLineItems == 1

def containsUnfulfilledItems(shopifyOrder):
    hmdOrderItemIDs = [8100195008729, 7693929054425, 7761325916377]
    hmdOrderItems = 0
    unfulfilledHmdOrderItems = 0
    for lineItem in shopifyOrder["line_items"]:
        if lineItem["product_id"] in hmdOrderItemIDs:
            hmdOrderItems += 1
            if lineItem["fulfillment_status"] == None:
                unfulfilledHmdOrderItems += 1
    return unfulfilledHmdOrderItems == hmdOrderItems

def getShopifyOrders(status, fulfillmentStatus = None, lineItemsInStock = False):
    ordersReturnedLimit = 200 # max is 200, apparently
    nextCursor = None
    allOrders = []
    orders = {f"ipd{i}": [] for i in range(55, 73) if i != 70}
    ordersInclRx = {f"ipd{i}": [] for i in range(55, 73) if i != 70}

    while(True):
        url = f"/admin/shop/shopify_orders?limit={ordersReturnedLimit}"
        if status != None:
            url += "&status=" + status
        if nextCursor != None:
            url += "&cursor=" + nextCursor
        if fulfillmentStatus != None:
            url += "&fulfillment_status=" + fulfillmentStatus
        data = BigApi.adminGet(url)

        for order in data["orders"]:
            if order.get("bigOrder") and containsUnfulfilledItems(order['shopifyOrder']) and containsBeyond(order['shopifyOrder']):
                if isValidOrder(order["shopifyOrder"]) == False:
                    #print(f"Ignoring order {order['shopifyOrder']['id']} because it is not valid")
                    pass
                else:
                    reqState = bigOrderRequirementState(order["bigOrder"], lineItemsInStock)
                    bigOrderIPD = order["bigOrder"]["ipd"]
                    if bigOrderIPD == 70:
                        bigOrderIPD = 69
                    if reqState == "outOfScope":
                        #print(f"Ignoring order {order['shopifyOrder']['id']} because it is waiting on more than just HMD and lenses")
                        pass
                    elif reqState == "hmdOnly":
                        allOrders.append(order)
                        orders[f"ipd{bigOrderIPD}"].append(order)
                        ordersInclRx[f"ipd{bigOrderIPD}"].append(order)
                    elif reqState == "hmdAndLenses":
                        allOrders.append(order)
                        ordersInclRx[f"ipd{bigOrderIPD}"].append(order)

        netOrderCount = len(allOrders)
        print(f"Orders accumulated: {netOrderCount}")
        if "nextCursor" in data:
            nextCursor = data["nextCursor"]

        if (len(data["orders"]) < ordersReturnedLimit):
            break
        if (len(orders) > 500):
            print("Breaking because order count passed the threshold")
            break   
    return {"allOrders": allOrders, "orders": orders, "ordersInclRx": ordersInclRx}


class FactoryKit:
    bs1Stock = {f"ipd{i}": 0 for i in range(55, 73) if i != 70}

    @staticmethod
    def init():
        BigApi.init(".admin.env")
        BigApi.adminLogin()

    @staticmethod
    def loadBs1Stock():
        BigApi.adminLogin()
        baseUrl = "/admin/inventory/items?limit=50&type=BigscreenBeyondV1&status=InStock&serialNumberLike=BS1"
        for key in FactoryKit.bs1Stock:
            url = baseUrl + key[-2:]
            data = BigApi.adminGet(url)
            FactoryKit.bs1Stock[key] = data["count"]
    
    @staticmethod
    def getUnmetDemandOrders():
        BigApi.adminLogin()
        shippedOrders = getShopifyOrders("open", None, False)
        return shippedOrders
    
    @staticmethod
    def getShippableOrders():
        BigApi.adminLogin()
        shippedOrders = getShopifyOrders("open", None, True)
        return shippedOrders