
import random
from datetime import datetime

import pycountry

from configs.firebase import SERVER_TIMESTAMP
from functions.ManualProducts import getManualProductMapping
from functions.Orders import (convertOrder, convertOrderItem,
                              convertShippingAddress, saveOrder)
from functions.Products import (getColorImages, getManualProductById,
                                getManualProductVariant, getProductById,
                                getProductsMapping, getProductVariant)
from functions.Response import API_Error
from functions.Shipments.Convert import getAddress
from functions.Shops import getShopById


def manualOrder(data):
    currentUser = data.get("currentUser")
    uid = currentUser.get("uid")
    enterpriseId = currentUser.get('enterpriseId')
    addressId = data.get("addressId")
    shopId = data.get("shopId")
    shop = None
    if shopId!="0"+uid: shop = getShopById(shopId)
    address = getAddress(addressId)
    items = data.get("items", [])
    if not (address):
        return API_Error("Missing required address fields")
    country = pycountry.countries.get(name=address.get("country"))
    if country: address['countryCode'] = country.alpha_2
    if not address.get("countryCode"): address['countryCode'] = address.get("country")
    if not items:
        return API_Error("Order can't be created with no items.")
    now = datetime.now()
    createdAt = int(now.timestamp())
    platformOrderId = f"{createdAt+random.randint(0,100)}{len(range(0, len(items)))}"
    orderItems = []
    total = 0
    manualProduct = False
    count = 0
    for item in items:
        productId, variantId, quantity = item.get("productId"), item.get("variantId"), int(item.get("quantity", 1))
        if not (productId or variantId or quantity):
            return API_Error("Missing required item fields.")
        product = getProductById(productId)
        if not product:
            product = getManualProductById(productId)
            manualProduct = True
            if not product:
                raise API_Error("Product not found", 404, dict(productId=productId))
        variant = getProductVariant(productId, variantId) if not manualProduct else getManualProductVariant(productId, variantId)
        if not variant:
            raise API_Error("Product variant not found.", 404, dict(productId=productId, variantId=variantId))
        productMapping, variantMapping = getProductsMapping(productId, variantId) if not manualProduct else getManualProductMapping(productId, variantId)
        if not (productMapping or variantMapping):
            raise API_Error("Product mapping not found, map the product/variant to use this variant.", 404, dict(productId=productId, variantId=variantId))
        if variant.get("price", 0): thisItemPrice = variant.get("price", 0) * quantity
        else: thisItemPrice = 0
        total += thisItemPrice
        image = None
        if product.get("images"): image = product.get("images")[0]
        color = None
        if variant.get("properties"): color = next((v.get("value") for v in variant.get("properties") if str(v.get("name", "")).lower() == "color"), None)
        mockups = getColorImages(productId=productId, blankProductId=variantMapping.get("blankProductId"), blankVariantId=variantMapping.get("blankVariantId"))
        if mockups: image = mockups[0]
        printImageColors  = [img.get("color") for img in variantMapping.get("images")] + [img.get("size") for img in variantMapping.get("images")]
        if color in printImageColors:
            printImages = [
                image for image in variantMapping.get("images") if color in [image.get("color"),image.get("size")] and (image.get("color") or image.get("size"))
                ]
        else:
            printImages = [
                image for image in variantMapping.get("images") if "default" in [image.get("color"),image.get("size")]
                ]
        if printImages: variantMapping['images'] = printImages
        orderItem = convertOrderItem(
            uid=uid,
            enterpriseId=enterpriseId,
            platformId='0',
            platformProductId=product.get("platformProductId"),
            platformOrderId=platformOrderId,
            platformOrderItemId=f"{platformOrderId}{count}",
            quantity=quantity,
            price=thisItemPrice,
            variantId=variantId,
            createdAt=SERVER_TIMESTAMP,
            updatedAt=SERVER_TIMESTAMP,
            shopId=shopId if shopId else uid+'0',
            product=product,
            name=product.get("name"),
            variant=variant,
            image=image,
            images=mockups,
            productMapping=productMapping,
            variantMapping=variantMapping,
            )
        orderItems.append(orderItem)
        count += 1
        manualProduct = False
    order =  convertOrder(
        uid=uid,
        platformId='0',
        shopId=shopId if shopId else uid+'0',
        shopName=shop.get("name") if shop else "Manual",
        enterpriseId=enterpriseId,
        shippingAddress=address,
        createdAt=SERVER_TIMESTAMP,
        updatedAt=SERVER_TIMESTAMP,
        grandTotal=total,
        platformOrderId=platformOrderId,
        totalPrice=total,
        metadata=dict(        )
    )
    orderId = saveOrder(order, orderItems)
    return dict(
        message=f"Order successfully added. {platformOrderId}",
        orderId=orderId,
    )