import json
import posixpath
import tempfile
import traceback
from datetime import datetime

import pytz
import requests

from V2.functions.Applications.main import Application
from V2.functions.Etsy.Products import tempImage
from V2.functions.Images.main import Image
from V2.functions.LastUpdate import LastUpdate
from V2.functions.Products.main import Product
from V2.functions.Products.Variants import Property, Variant
from V2.functions.Shops.main import Shop, getShopsByPlatformId
from V2.functions.Squarespace.Auth import SquarespaceClient
from V2.middlewares.auth import API_Error
from V2.Params import Params


def updateAllProducts(params:Params):
    shops = getShopsByPlatformId(platformId="10", credentials= True)
    return str([updateShopProducts(shop) for shop in shops])

def updateShopProducts(shop:Shop):
    try:    
        shopId = shop.id
        application = Application.get(shop.appId)
        update = LastUpdate.get(shopId, "products")
        client = SquarespaceClient(application,shop)
        products, pagination = getProducts(client=client,lastUpdated=update)
        savedProducts = []
        for product in products:
            platformProductId =str( product.get("id"))
            images= [Image(id=i.get("id"),name=i.get("altText"),url=i.get("url")) for i in product.get("images")]
            price= min([
                float(v.get("pricing").get("basePrice").get("value")) for v in product.get('variants')
            ])
            convertedProduct = Product(
                id=shop.platformId+shop.id+platformProductId,
                uid=shop.uid, 
                platformId=shop.platformId,
                shopId=shopId,
                enterpriseId=shop.enterpriseId,
                platformProductId=platformProductId,
                name = product.get("name"),
                description = product.get("description"),
                createdAt= datetime.strptime(product.get("createdOn"), "%Y-%m-%dT%H:%M:%S.%fZ"),
                updatedAt= datetime.strptime(product.get("modifiedOn"), "%Y-%m-%dT%H:%M:%S.%fZ"),
                price = price,
                tags = list(product.get("tags", [])),
                images = images
            )
            variants = [Variant(
                id=variant.get("id"),
                uid=shop.uid,
                enterpriseId=shop.enterpriseId,
                productId=convertedProduct.id,
                # ignore sku for app.myshirtpod.com
                sku = None if shop.enterpriseId == "lJ2eUFov5WyPlRm4geCr" else  variant.get('sku'),
                price=variant.get("pricing").get("value"),
                properties=[Property(
                    name=prop,
                    value=value
                ) for prop,value in variant.get("attributes").items()]
            ) for variant in product.get("variants")]
            savedProducts.append(convertedProduct.save(variants=variants))
        update.save(
            count=len(savedProducts),
            nextPage=pagination.get("nextPageCursor") if pagination.get("hasNextPage")  else None
        )
    except Exception as e:
        print(traceback.format_exc())
        return str(e)
    return f"Products Updated => {len(savedProducts)}"


def updateSingleSquarespaceProduct(shop: Shop, platformProductId:str):
    app = Application.get(shop.appId)
    client = SquarespaceClient(app, shop)
    product = getSquarespaceProduct(client, platformProductId)
    platformProductId =str( product.get("id"))
    images= [Image(id=i.get("id"),name=i.get("altText"),url=i.get("url")) for i in product.get("images")]
    price= min([
        float(v.get("pricing").get("basePrice").get("value")) for v in product.get('variants')
    ])
    convertedProduct = Product(
        id=shop.platformId+shop.id+platformProductId,
        uid=shop.uid, 
        platformId=shop.platformId,
        shopId=shop.id,
        enterpriseId=shop.enterpriseId,
        platformProductId=platformProductId,
        name = product.get("name"),
        description = product.get("description"),
        createdAt= datetime.strptime(product.get("createdOn"), "%Y-%m-%dT%H:%M:%S.%fZ"),
        updatedAt= datetime.strptime(product.get("modifiedOn"), "%Y-%m-%dT%H:%M:%S.%fZ"),
        price = price,
        tags = list(product.get("tags", [])),
        images = images
    )
    variants = [Variant(
        id=variant.get("id"),
        uid=shop.uid,
        enterpriseId=shop.enterpriseId,
        productId=convertedProduct.id,
        # ignore sku for app.myshirtpod.com
        sku = None if shop.enterpriseId == "lJ2eUFov5WyPlRm4geCr" else  variant.get('sku'),
        price=variant.get("pricing").get("value"),
        properties=[Property(
            name=prop,
            value=value
        ) for prop,value in variant.get("attributes").items()]
    ) for variant in product.get("variants")]
    return convertedProduct.save(variants=variants)

def getProducts(client:SquarespaceClient,lastUpdated:LastUpdate) -> tuple[list, dict]:
    url = f"https://api.squarespace.com/{client.shop.apiVersion}/commerce/products"
    res = client.get(url, params=dict(
        cursor=lastUpdated.nextPage if isinstance(lastUpdated.nextPage, str) else None
    ))
    # print(res.text)
    if res.status_code == 200: return res.json().get("products", []), res.json().get("pagination")
    raise API_Error(res.text, res.status_code)

def getSquarespaceProduct(client: SquarespaceClient, platformProductId:str):
    url = f"https://api.squarespace.com/1.1/commerce/products/{platformProductId}"
    res = client.get(url)
    # print(res.text)
    if res.status_code == 200: return res.json().get("products")[0]
    raise API_Error(res.text, res.status_code)


def submitToSquarespace(shop: Shop, name, description, variants, tags=[], colorImages={}):
    accessToken = shop.accessToken
    headers = {
        "Authorization": f"Bearer {accessToken}",
        "Content-Type": "application/json"
    }

    formatted_variants = []
    images =[]
    for color, imgs in colorImages.items():
        images.extend({
            "color": color,
            "url": img.get("url"),
        } for img in imgs) 
    for variant in variants:
        attributes = {
            "Color": variant.get("color") if variant.get("color") else "One Color",
            "Size": variant.get("size") if variant.get("size") else "One Size"
        }
        formatted_variants.append({
            "sku": variant.get("sku"),
            "pricing": {
                "basePrice":{
                    "currency": "USD",
                    "value": str(variant.get("price"))
                }
            },
            "attributes": attributes,
            "shippingMeasurements": {
                "weight": {
                    "value": 0.5,
                    "unit": "POUND"
                },
                 "dimensions": {
                    "unit": "INCH",
                    "width": 5.0,
                    "height": 5.0,
                    "length": 7.0
                 } 
            },
            "stock":{
            "unlimited": True,
        }
        })
    storePagesRequest = requests.get(f"https://api.squarespace.com/1.0/commerce/store_pages", headers=headers)
    storePageId = ""
    if storePagesRequest.status_code == 200:
        storePages = storePagesRequest.json().get("storePages", [])
        storePageId = storePages[0].get("id") if storePages else ""
    payload = {
        "name": name,
        "description": description,
        "type": "PHYSICAL",
        "variants": formatted_variants,
        "tags": tags,
        "storePageId":storePageId,
        "variantAttributes": ["Size", "Color"],
        "isVisible": True,
        
        # "images": [img.get("url") for img in images]
    }
    
    response = requests.post(f"https://api.squarespace.com/1.1/commerce/products", headers=headers, json=payload)
    if response.status_code in [200, 201]:
        data = response.json()
        productId = data.get("id")
        print(data)
        for image in images:
            name = image.get("name")
            color = image.get("color")
            if not name:  name = image.get("color", "") + posixpath.basename(image.get("url"))
            path = tempImage(name, image.get("url"))
            # files = {
            #     "filename": open(path, "rb").read(),
            #     "name": name
            # }
            # print(files)
            # image_request = requests.post(
            #                             f"https://api.squarespace.com/1.1/commerce/products/{response.json().get('id')}/images",
            #                             headers={
            #                                 "Content-Type":"multipart/form-data",
            #                                 "Authorization": f"Bearer {accessToken}",
            #                             },
            #                             files=files,
            #                             data={}
                                # )
            with open(path, "rb") as f:
                files = {
                    "file": (name, f, "image/png")  # Or "image/jpeg" based on actual file type
                }

                headers = {
                    "Authorization": f"Bearer {accessToken}",
                    "User-Agent": "RIVERR"  # Optional but recommended
                    # DO NOT manually set "Content-Type" for multipart/form-data — requests handles it
                }

                image_request = requests.post(
                    f"https://api.squarespace.com/1.0/commerce/products/{productId}/images",
                    headers=headers,
                    files=files
                )
                # After uploading image:
                imageId = image_request.json().get("id")

                # For each variant that matches the color:
                for variant in data.get("variants", []):
                    if variant.get("attributes", {}).get("Color") == color:
                        variantId = variant.get("id")
                        print("assigning image to variant", variantId, image.get("url"))
                        assignImageToVariant(shop, productId, variantId, imageId)
        variants_map = {v.get("sku"): v.get("id") for v in data.get("variants", [])}
        return productId, variants_map

    raise API_Error(response.text, response.status_code)


def assignImageToVariant(shop: Shop, productId: str, variantId: str, imageId: str):
    accessToken = shop.accessToken
    url = f"https://api.squarespace.com/1.0/commerce/products/{productId}/variants/{variantId}/image"
    headers = {
        "Authorization": f"Bearer {accessToken}",
        "Content-Type": "application/json",
        "User-Agent": "Riverr"
    }
    payload = {
        "imageId": imageId  # or use None to remove image
    }
    response = requests.post(url, headers=headers, json=payload)
    print(response.status_code, response.text)
    if response.status_code in [200, 204]:
        return True
    raise API_Error(response.text, response.status_code)