import traceback
from datetime import datetime

from requests_oauthlib import OAuth1Session

from functions.Applications import getAppCredentials
from functions.LastUpdated import productsLastUpdated, saveProductsLastUpdated
from functions.Products import (convertImage, convertProduct, convertProperty,
                                convertVariant, saveProduct)
from functions.Response import API_Error
from functions.Shops import getShopById, getShops
from functions.Suppliers.BlankProducts import worker


def updateAllProducts(params={}):
    shops = getShops(platformId="1", credentials= True)
    shops = [shop for shop in shops if not shop.get("apiVersion")]
    res =  worker(updateShopProducts, shops)
    return str(res)

def updateShopProducts(shop):
    if shop:
        try:
            shopId = shop.get('id')
            savedProducts = []
            uid = shop.get('uid')
            enterpriseId = shop.get('enterpriseId')
            oauthToken = shop.get("oauthToken")
            oauthTokenSecret = shop.get("oauthTokenSecret")
            applicationId = shop.get("appId")
            application = getAppCredentials(applicationId)
            lastUpdate = productsLastUpdated(shopId)
            currentPage = lastUpdate.get("nextPage")
            platformShopId = shop.get("platformShopId")
            platformId = shop.get("platformId")
            oauth = OAuth1Session(application.get("apiKey"), application.get("apiSecret"), oauthToken, oauthTokenSecret)
            params = dict(limit=100, page=currentPage, sort_on="created")
            print(params)
            response = oauth.get(f"https://openapi.etsy.com/v2/shops/{str(platformShopId)}/listings/active", params=params)
            if response.status_code ==  200:
                jsonres = response.json()
                products = jsonres.get("results", [])
                totalProducts = jsonres.get('count')
                totalPages = int(totalProducts/100)+1
                for product in products:
                    id = product.get("listing_id")
                    images = []
                    imagesRes = oauth.get(f"https://openapi.etsy.com/v2/listings/{id}/images")
                    if imagesRes.status_code == 200:
                        imagesJson = imagesRes.json().get("results", [])
                        images=  [convertImage(id=i.get("listing_image_id"), url = i.get("url_fullxfull"), primary= i.get("rank", 1) == 1) for i in imagesJson]
                    convertedProduct = convertProduct(
                        uid=uid, 
                        platformId=platformId,
                        shopId=shopId,
                        enterpriseId=enterpriseId,
                        platformProductId=id,
                        name = product.get("title"),
                        description = product.get("description"),
                        createdAt= datetime.fromtimestamp(product.get("creation_tsz")),
                        updatedAt= datetime.now(),
                        price = float(product.get("price")),
                        tags = list(product.get("tags", [])),
                        images = images
                    )
                    variants = []
                    variantsRes = oauth.get(f"https://openapi.etsy.com/v2/listings/{id}/inventory")
                    if variantsRes.status_code == 200:
                        variantsJson = variantsRes.json().get('results', {}).get("products", [])
                        variants = [
                            convertVariant(
                                id = v.get('product_id'),
                                properties=[convertProperty(
                                    id =str(p.get('property_id')), 
                                    name = p.get('property_name'), 
                                    value = p.get('values', ["None"])[0]) for p in v.get('property_values', [])],
                                    deleted= v.get('is_deleted', False), 
                                    sku = v.get('sku')) for v in variantsJson
                            ]
                    savedProducts.append(saveProduct(convertedProduct, variants))
                saveProductsLastUpdated(shopId = shopId, count = len(savedProducts), lastPage= currentPage,total=totalPages, nextPage = currentPage+1 if totalPages > currentPage else 1)
            else: raise API_Error(response.text, response.status_code, meta=dict(shopId=shopId, msg = response.text))
        except Exception as e:
            print(traceback.format_exc())
            return str(e)
        return f"Products Updated => {len(savedProducts)}"
    return "No updates"

def getTaxonomies(params):
    enterpriseId = params.get('currentUser').get('enterpriseId')
    app = getAppCredentials("1"+enterpriseId)
    shopId = params.get('shopId')
    shop = getShopById(shopId, True)
    oauth = OAuth1Session(app.get('apiKey'), app.get('apiSecret'), shop.get('oauthToken'), shop.get('oauthTokenSecret'))
    res = oauth.get("https://openapi.etsy.com/v2/taxonomy/seller/get")
    if res.status_code == 200:
        return dict(taxanomy= [dict(id=t.get('id'), name = t.get('name')) for t in res.json().get('results')])
    raise API_Error(res.text, res.status_code)

def getShippingTemplates(params):
    currentUser = params.get('currentUser')
    uid, enterpriseId = currentUser.get('uid'),currentUser.get('enterpriseId')
    shopId = params.get('shopId')
    app = getAppCredentials("1"+enterpriseId)
    shop = getShopById(shopId, True)
    oauth = OAuth1Session(app.get('apiKey'), app.get('apiSecret'), shop.get('oauthToken'), shop.get('oauthTokenSecret'))
    res = oauth.get("https://openapi.etsy.com/v2/users/__SELF__/shipping/templates")
    if res.status_code == 200:
        return dict(shippingTemplates= res.json().get('results'))
    raise API_Error(res.text, res.status_code)


def updateSingleProduct(platformProductId:str,shop:dict):
    shopId = shop.get('id')
    try:
            uid = shop.get('uid')
            enterpriseId = shop.get('enterpriseId')
            oauthToken = shop.get("oauthToken")
            oauthTokenSecret = shop.get("oauthTokenSecret")
            applicationId = shop.get("appId")
            application = getAppCredentials(applicationId)
            lastUpdate = productsLastUpdated(shopId)
            currentPage = lastUpdate.get("nextPage")
            platformShopId = shop.get("platformShopId")
            platformId = shop.get("platformId")
            oauth = OAuth1Session(application.get("apiKey"), application.get("apiSecret"), oauthToken, oauthTokenSecret)
            params = dict(limit=100, page=currentPage, sort_on="created")
            response = oauth.get(f"https://openapi.etsy.com/v2/listings/{platformProductId}", params=params)
            if response.status_code ==  200:
                jsonres = response.json()
                products = jsonres.get("results", [])
                for product in products:
                    id = product.get("listing_id")
                    images = []
                    imagesRes = oauth.get(f"https://openapi.etsy.com/v2/listings/{id}/images")
                    if imagesRes.status_code == 200:
                        imagesJson = imagesRes.json().get("results", [])
                        images=  [convertImage(id=i.get("listing_image_id"), url = i.get("url_fullxfull"), primary= i.get("rank", 1) == 1) for i in imagesJson]
                    convertedProduct = convertProduct(
                        uid=uid, 
                        platformId=platformId,
                        shopId=shopId,
                        enterpriseId=enterpriseId,
                        platformProductId=id,
                        name = product.get("title"),
                        description = product.get("description"),
                        createdAt= datetime.fromtimestamp(product.get("creation_tsz")),
                        updatedAt= datetime.now(),
                        price = float(product.get("price")),
                        tags = list(product.get("tags", [])),
                        images = images
                    )
                    variants = []
                    variantsRes = oauth.get(f"https://openapi.etsy.com/v2/listings/{id}/inventory")
                    if variantsRes.status_code == 200:
                        variantsJson = variantsRes.json().get('results', {}).get("products", [])
                        variants = [
                            convertVariant(
                                id = v.get('product_id'),
                                properties=[convertProperty(
                                    id =str(p.get('property_id')), 
                                    name = p.get('property_name'), 
                                    value = p.get('values', ["None"])[0]) for p in v.get('property_values', [])],
                                    deleted= v.get('is_deleted', False), 
                                    sku = v.get('sku')) for v in variantsJson
                            ]
                    return saveProduct(convertedProduct, variants)
            else: raise API_Error(response.text, response.status_code, meta=dict(shopId=shopId, msg = response.text))
    except Exception as e:
            print(traceback.format_exc())
            raise API_Error(str(e),500, meta=dict(shopId=shopId, msg = str(e)))
