import traceback
from datetime import datetime

import pytz

from V2.functions.Address.main import Address
from V2.functions.Applications.main import Application
from V2.functions.Ebay.Auth import EbayClient
from V2.functions.LastUpdate import LastUpdate
from V2.functions.Orders.main import Order
from V2.functions.Orders.OrderItem import OrderItem
from V2.functions.Shops.main import Shop, getShopsByPlatformId
from V2.middlewares.auth import API_Error
from V2.Params import Params


def updateAllOrders(params:Params):
    shops = getShopsByPlatformId(platformId="9",credentials=True)
    return str([updateShopOrders(shop) for shop in shops])

def updateShopOrders(shop:Shop):
    try:
        shopId = shop.id
        updates:list[str] = []
        application = Application.get(shop.appId)
        lastUpdate = LastUpdate.get(shopId)
        client = EbayClient(application, shop)
        orders:list[dict] = getEbayOrders(client=client, lastUpdated=lastUpdate.timestamp)
        print("updating orders", shopId, len(orders))
        for order in orders:
            platformOrderId = order.get('orderId')
            items = order.get("lineItems", [])
            orderItems:list[OrderItem] = []
            address:dict = order.get("fulfillmentStartInstructions",[])[0].get("shippingStep")
            if not address: continue
            for item in items:
                orderItem = OrderItem(
                    uid=shop.uid,
                    enterpriseId=shop.enterpriseId,
                    platformId=shop.platformId,
                    platformProductId= item.get('legacyItemId', item.get("listingId")),
                    platformOrderItemId=item.get('lineItemId'),
                    platformOrderId = platformOrderId,
                    quantity = item.get('quantity'),
                    price = item.get('lineItemCost').get("value"),
                    discount = 0,
                    tax=sum(t.get("amount").get("value") for t in item.get("taxes", [])),
                    subtotal=item.get('lineItemCost').get("value")*item.get('quantity'),
                    total=item.get('total').get("value"),
                    variantId= str(item.get('legacyVariationId')),
                    name=item.get('title'),
                    shopId=shopId, 
                    createdAt= datetime.fromisoformat(order.get("creationDate", '')),
                    updatedAt= datetime.fromtimestamp(order.get('lastModifiedDate','')),
                    productId=shop.platformId+shop.id+str(item.get('legacyItemId', item.get("listingId"))),
                )
                orderItems.append(orderItem)
            convertedOrder = Order(
                uid=shop.uid,
                platformId=shop.platformId,
                shopId=shopId,
                enterpriseId=shop.enterpriseId,
                cancelled=order.get("cancelStatus") == "NONE_REQUESTED",
                draft=False,
                shippingAddress=Address(
                    name=address.get('fullName'),
                    address1=address.get("contactAddress",{}).get('addressLine1'),
                    address2=address.get("contactAddress",{}).get('addressLine2'),
                    city=address.get("contactAddress",{}).get('city'),
                    state=address.get("contactAddress",{}).get('stateOrProvince'),
                    zip=address.get("contactAddress",{}).get('postalCode'),
                    country=address.get("contactAddress",{}).get('country'),
                    countryCode=address.get("contactAddress",{}).get('countryCode'),
                    email=address.get('email'),
                    phone=address.get('primaryPhone'),
                ),
                platformOrderId=platformOrderId, 
                createdAt = datetime.fromisoformat(order.get('creationDate','')),
                updatedAt= datetime.fromisoformat(order.get('lastModifiedDate','')),
                grandTotal= sum(item.total for item in orderItems),
                shipped= order.get('orderFulfillmentStatus') == "FULFILLED",
                currencyCode= order.get("PricingSummary",{}).get('total').get('value'),
                shippingCost= order.get("PricingSummary",{}).get('deliveryCost').get('value'),
                totalDiscount= order.get('PricingSummary',{}).get("deliveryDiscount", {}).get("value")+order.get('PricingSummary',{}).get("priceDiscountSubtotal",{}).get("value"),
                totalTax= order.get('PricingSummary',{}).get("tax").get("value"),
                totalPrice= order.get('PricingSummary',{}).get("priceSubtotal").get("value"),
                shopName=shop.name,
            )
            updates.append(convertedOrder.save(orderItems))
        lastUpdate.save(count=len(updates))
        return lastUpdate
    except Exception as e:
        traceback.print_exc()
        return str(e)

def getEbayOrders(client:EbayClient, lastUpdated:int, limit:int=200) -> list[dict]:
    url = f"https://api.ebay.com/sell/fulfillment/v1/order"
    date = datetime.fromtimestamp(lastUpdated)
    #"2016-05-15T08:25:43.511Z.."
    lastModified = f"lastmodifieddate:[{date.isoformat()}.291Z..]"
    print(lastModified)
    res = client.get(
        url, 
        params=dict(
            filter=lastModified,
            limit=limit,
        ),
    )
    print(res.text)
    if res.status_code == 200:
        return res.json().get("orders", [])
    raise API_Error(res.text, res.status_code)


def submitShipment(shop:Shop, platformOrderId:str, trackingCode:str, carrierName:str):
    app = Application.get(shop.appId)
    client = EbayClient(app,shop)
    url = f"https://openapi.etsy.com/v3/application/shops/{shop.platformShopId}/receipts/{platformOrderId}/tracking"
    res = client.post(
        url=url, 
        data=dict(
            carrier_name=carrierName,
            tracking_code=trackingCode,
            send_bcc=True
        )
    )
    if res.status_code == 200: return True
    print(res.text, res.status_code)
    return False