import random
from datetime import datetime

import stripe

from configs.firebase import SERVER_TIMESTAMP, db
from functions.Invoices import getStripeCreds
from functions.Orders import convertOrder, convertOrderItem, saveOrder
from functions.Products import getProductById, getProductVariant
from V2.functions.Address.main import Address
from V2.functions.Images.main import Image
from V2.functions.Orders.main import Order
from V2.functions.Orders.OrderItem import OrderItem
from V2.functions.Products.main import Product, Variant
from V2.functions.Shops.main import Shop, getPopupStore
from V2.middlewares.auth import API_Error
from V2.Params import Params, PublicParams


def completeCheckoutSession(params: Params):
    checkoutSessionId = params.args.get("checkoutSessionId")
    enterprise = params.args.get("enterprise")
    stripeCreds = getStripeCreds(enterprise.get("id"))
    stripe.api_key = stripeCreds.get("apiSecret")
    checkoutSession = stripe.checkout.Session.retrieve(checkoutSessionId).to_dict()
    paymentStatus = checkoutSession.get("payment_status")
    if paymentStatus != "paid":
        raise API_Error(
            "Payment Failed.", 400, dict(checkoutSessionId=checkoutSessionId)
        )
    customizationId = checkoutSession.get("metadata", {}).get("customizationId")
    if not customizationId:
        raise API_Error(
            "Customization Failed.", 400, dict(checkoutSessionId=checkoutSessionId)
        )
    customizationDetails = (
        db.collection("stripeCheckouts").document(customizationId).get()
    )
    if not customizationDetails.exists:
        raise API_Error(
            "Customization Failed.", 400, dict(checkoutSessionId=checkoutSessionId)
        )
    customizationDetails = customizationDetails.to_dict()
    customerDetails = customizationDetails.get("customer_details")
    if not customerDetails.get("address"):
        raise API_Error(
            "Address not found.", 400, dict(checkoutSessionId=checkoutSessionId)
        )
    address = customerDetails.get("address")
    shippingAddresss = Address(
        name=customerDetails.get("name"),
        address1=address.get("line1"),
        address2=address.get("line2"),
        zip=address.get("postal_code"),
        state=address.get("state"),
        country=address.get("country"),
        countryCode=address.get("country"),
    )


def stripeCustomizer(params: PublicParams):
    products = params.args.get("products")
    shippingAddress = params.args.get("shippingAddress")
    shippingRate = params.args.get("shippingRate", {})
    hostname = params.hostname
    enterprise = params.enterprise
    enterpriseId = enterprise.get("id")
    stripeCreds = getStripeCreds("cfbZh6XFBG3usCcUwpRE")
    stripe.api_key = stripeCreds.get("apiSecret")
    createdProducts = []
    customizationId = str(int(datetime.now().timestamp()))
    for p in products:
        product, variations = p.get("product"), p.get("variations")
        for variation in variations:
            color = variation.get("color")
            size = variation.get("size")
            price = variation.get("price")
            images = [v.get("url") for v in variation.get("images", {})]
            name = product.get("name")
            # product = stripe.Product.create(
            #     name = params.args.get("name"),
            #     metadata = params.args.get("metadata"),
            #     default_price_data = dict(
            #         currency = params.args.get("currency"),
            #         unit_amount_decimal = int(price*100),
            #     )
            # )
            createdProduct = stripe.Product.create(
                name=f"{name} -{color}-{size}",
                images=images,
                default_price_data=dict(
                    currency=params.args.get("currency", "USD"),
                    unit_amount=int(price * 100),
                ),
                metadata=dict(customizationId=customizationId),
                shipping_address_collection=dict(allowed_countries=["US", "CA"]),
                shippable=True,
            )
            createdProducts.append(createdProduct)
    checkout_session = stripe.checkout.Session.create(
        line_items=[
            {
                # Provide the exact Price ID (for example, pr_1234) of the product you want to sell
                "price": p.get("default_price"),
                "quantity": 1,
            }
            for p in createdProducts
        ],
        mode="payment",
        success_url="https://"
        + hostname
        + "/checkout-success?checkoutSessionId={CHECKOUT_SESSION_ID}",
        cancel_url="https://"
        + hostname
        + "/checkout-failure?checkoutSessionId={CHECKOUT_SESSION_ID}",
        automatic_tax={"enabled": True},
    ).to_dict()
    db.collection("stripeCheckouts").document(customizationId).set(
        dict(
            **params,
            shippingRate=shippingRate,
            shippingAddress=shippingAddress,
            session=checkout_session.to_dict(),
            id=customizationId,
            sessionId=checkout_session.get("id"),
        )
    )
    return dict(checkout_url=checkout_session.get("url"))
# import json

# print(json.dump((db.document("stripeCheckouts/pi_3RQZz7Kc34kmwhxF0OPS6BF3").get().to_dict()), indent=4))

# def PopupStoreCheckout(params:Params):
#     print((params))/stripeCheckouts/pi_3RQZz7Kc34kmwhxF0OPS6BF3
#     products = params.args.get("products")
#     hostname = params.hostname
#     stripeCreds = getStripeCreds("cfbZh6XFBG3usCcUwpRE")
#     stripe.api_key = stripeCreds.get("apiSecret")
#     createdProducts = []
#     customizationId = str(int(datetime.now().timestamp()))
#     print(products)
#     for p in products:
#         id, quantity, variantId = p.get("id"), p.get("quantity"), p.get("variantId")
#         product = getProductById(id)
#         variant = getProductVariant(id, variantId)
#         # color = variation.get("color")
#         # size = variation.get("size")
#         price = variant.get("price")
#         images = [v.get("url") for v in variant.get("images",{})]
#         name = product.get('name')
#         # product = stripe.Product.create(
#         #     name = params.args.get("name"),
#         #     metadata = params.args.get("metadata"),
#         #     default_price_data = dict(
#         #         currency = params.args.get("currency"),
#         #         unit_amount_decimal = int(price*100),
#         #     )
#         # )
#         createdProduct = stripe.Product.create(
#             name=f"{name}",
#             images=images,
#             default_price_data=dict(
#                 currency=params.args.get("currency", "USD"),
#                 unit_amount=int(price * 100)*int(quantity)
#             ),
#             metadata=dict(
#                 customizationId=customizationId
#             ),
#             shipping_address_collection=dict(
#                 allowed_countries=["US", "CA"]
#             ),
#             shippable=True
#         )
#         createdProducts.append(createdProduct)
#     checkout_session = stripe.checkout.Session.create(
#         line_items=[
#             {
#                 # Provide the exact Price ID (for example, pr_1234) of the product you want to sell
#                 'price':p.get("default_price"),
#                 'quantity': 1,
#             } for p in createdProducts
#         ],
#         mode='payment',
#         success_url="https://"+hostname+"/checkout-success?checkoutSessionId={CHECKOUT_SESSION_ID}",
#         cancel_url="https://"+hostname+"/checkout-failure?checkoutSessionId={CHECKOUT_SESSION_ID}",
#         automatic_tax={'enabled': True},
#     ).to_dict()
#     db.collection("stripeCheckouts").document(customizationId).set(dict(
#         **params,
#         session=checkout_session.to_dict(),
#         id=customizationId,
#         sessionId = checkout_session.get("id")
#     ))
#     return dict(checkout_url = checkout_session.get("url"))


def getCheckoutSession(params: Params):
    ref = db.collection("stripeCheckouts").document(params.id).get()
    if ref.exists:
        session = ref.to_dict()
        orderId = session.get("orderId")
        if orderId:
            order = Order.get(orderId).to_dict()
            if order:
                return dict(
                    order=order,
                    orderItems=[
                        item.to_dict() for item in OrderItem.getByOrderId(orderId)
                    ],
                    status="completed",
                )
        return dict(status=session.get("status"), id=params.id)
    return None


def PopupStoreCheckout(params: Params):
    products = params.args.get("products")
    shippingRate = params.args.get("shippingRate", {})
    shippingAddress = params.args.get("shippingAddress", {})
    shippingCost = int(shippingRate.get("cost", 0) * 100)
    hostname = params.hostname
    stripeCreds = getStripeCreds("cfbZh6XFBG3usCcUwpRE")
    stripe.api_key = stripeCreds.get("apiSecret")
    publishableKey = stripeCreds.get("apiKey")
    if hostname in ["spstore.mycart.me", "christmas.mycart.me"]:
        stripe.api_key = stripeCreds.get("apiSecretTest")
        publishableKey = stripeCreds.get("apiKeyTest")
    # line_items = []  # Initialize line_items here
    shop = getPopupStore(hostname)
    amount = 0
    for p in products:
        id, quantity, variantId = p.get("id"), p.get("quantity"), p.get("variantId")
        customized = p.get("customized")
        price = 0
        if customized: 
            customizationId = p.get("customizationId")
            customizationDetails = db.document(f"popupStoreCartPlacements/{customizationId}").get().to_dict()
            if customizationDetails:
                variation = customizationDetails.get("variations")[0]
                price = variation.get("price")
        else:
            variant = getProductVariant(id, variantId)
            price = variant.get("price")
        amount += int(price * quantity * 100)
        # Create a Price object for each product variant
        # price_data = dict(
        #     unit_amount=int(price * 100),
        #     currency=params.args.get("currency", "USD"),
        #     product_data={
        #                     'name':name,
        #                     "images":images,
        #             },
        # )
        # print(price_data)
        # tax_behavior='exclusive'  # Or 'inclusive' if your price includes tax
        # Add the Price ID and quantity to line_items
        # line_items.append({
        #     'price_data': price_data,
        #     'quantity': quantity,
        # })
    # print(line_items)
    # Create a Checkout Session
    # checkout_session = stripe.checkout.Session.create(
    #     line_items=line_items,  # Use the created line_items
    #     mode='payment',
    #     shipping_address_collection={"allowed_countries": ["US", "CA"]},
    #     success_url=f"https://{hostname}/checkout-success?checkoutSessionId={{CHECKOUT_SESSION_ID}}",
    #     cancel_url=f"https://{hostname}/checkout-failure?checkoutSessionId={{CHECKOUT_SESSION_ID}}",
    #     automatic_tax={'enabled': False},
    #     # tax_behavior='exclusive'
    # )
    # # Retrieve the PaymentIntent ID from the Checkout Session
    # paymentIntentId = checkout_session.get("payment_intent")
    # # Store the Checkout Session details in the database
    # db.collection("stripeCheckouts").document(checkout_session.get("id")).set(dict(
    #     session=dict(checkout_session),
    #     id=checkout_session.get("id"),
    #     paymentIntentId=paymentIntentId,
    #     hostname=hostname,
    #     products=products,
    #     status="pending",
    #     orderId=None,
    #     uid=shop.uid,
    #     enterpriseId=shop.enterpriseId,
    #     shopId=shop.id
    # # ))
    # return dict(
    #     checkout_url=checkout_session.get("url"),
    #     id=checkout_session.get("id"),
    #     paymentIntentId=paymentIntentId
    # )

    # Create a PaymentIntent
    taxCalculation = stripe.tax.Calculation.create(
        currency="usd",
        customer_details={
            "address": {
                "line1": shippingAddress.get("line1"),
                "city": shippingAddress.get("city"),
                "state": shippingAddress.get("state"),
                "postal_code": shippingAddress.get("zip"),
                "country": shippingAddress.get("country"),
            },
            "address_source": "shipping",
        },
        line_items=[
            {
                "amount": amount,
                "reference": "decorated_tshirt",
                "tax_behavior": "exclusive",
                "tax_code": "txcd_99999999",
            },
        ],
        shipping_cost={
            "amount": shippingCost,
            "tax_behavior": "exclusive",
            "tax_code": "txcd_92010001",
        },
        expand=["line_items"],
    )
    tax = int(taxCalculation.get("tax_amount_exclusive"))
    total = amount + shippingCost + tax
    transferGroupId = str(int(datetime.now().timestamp()))
    connectAccountId = getConnectAccountId(shop.uid)
    payment_intent = stripe.PaymentIntent.create(
        amount=total,
        currency=params.args.get("currency", "USD"),
        payment_method_types=["card"],
        on_behalf_of=connectAccountId,
        transfer_group=transferGroupId,
    )
    # Store PaymentIntent in your database
    amounts = dict(
        tax=round(tax / 100, 2),
        shippingCost=round(shippingCost / 100, 2),
        totalCost=round(total / 100, 2),
        subtotal=round(amount / 100, 2),
    )
    db.collection("stripeCheckouts").document(payment_intent.get("id")).set(
        dict(
            id=payment_intent.get("id"),
            status="pending",
            hostname=hostname,
            products=products,
            uid=shop.uid,
            enterpriseId=shop.enterpriseId,
            shopId=shop.id,
            shippingAddress=shippingAddress,
            shippingRate=shippingRate,
            createdAt=datetime.now(),
            updatedAt=datetime.now(),
            transferGroupId=transferGroupId,
            connectAccountId=connectAccountId,
            paymentIntentId=payment_intent.get("id"),
            **amounts,
        )
    )

    return dict(
        clientSecret=payment_intent.get("client_secret"),
        publishableKey=publishableKey,
        paymentIntentId=payment_intent.get("id"),
        id=payment_intent.get("id"),
        **amounts,
    )


def createConnectAccount(params: Params):
    import stripe

    stripe.api_key = "sk_live_rQt2VpSDVdmNs8Ayf8YwUWMc"
    if not params.currentUser.connectAccountId:
        account = stripe.Account.create(
            country="US",
            # email=params.currentUser.email,:
            capabilities= {
                "card_payments": {"requested": True},
                "transfers": {"requested": True},
            },
            controller={
                "fees": {"payer": "application"},
                "losses": {"payments": "application"},
                "stripe_dashboard": {"type": "express"},
            },
            settings={
                "payouts": {
                    "schedule": {"interval": "weekly", "weekly_anchor": "sunday"},
                }
            },
        )
        accountId = account.get("id")
        params.currentUser.update(connectAccountId=accountId)
    else:
        account = stripe.Account.retrieve(params.currentUser.connectAccountId)
        accountId = account.get("id")
    login_link = stripe.AccountLink.create(
        account=accountId,
        refresh_url=f"https://{params.hostname}",
        return_url=f"https://{params.hostname}",
        type="account_onboarding",
    )
    return dict(login_link)


def stripeConnectWebhook(params, test=False):
    """
    Stripe Webhook to handle events and complete an order after payment is successful.
    """
    payload = params.data
    sig_header = params.headers.get("Stripe-Signature")
    webhookSecret = "whsec_cvfaN7T65hpn2OTpwGiqj2HQ9zYlxHnc"
    if test:
        webhookSecret = "whsec_TmxVNud1elMOZKUxHspJEb9jl0HXEsxj"
    try:
        event = stripe.Webhook.construct_event(
            # payload, sig_header, "whsec_gnFqLSoXwYorA5mzUIpHmDuPhbI0ja2N"
            #    payload, sig_header,  "whsec_BPJwdgvO1JWTv08mNXFQuvCkkPoiZduJ"
            payload,
            sig_header,
            webhookSecret,
        )
    except ValueError:
        print({"error": "Invalid payload"})
        return {"error": "Invalid payload"}, 400
    except stripe.error.SignatureVerificationError:
        print({"error": "Invalid signature"})
        return {"error": "Invalid signature"}, 400

    # Handle relevant Stripe event types
    if event["type"] == "payment_intent.succeeded":
        intent = event["data"]["object"]
        paymentIntentId = intent.get("id")
        return completeOrder(paymentIntentId)
    return {"message": "Invalid event type"}, 200

def getConnectAccountId(uid:str):
    """
    Function to get the connected account ID for a user.
    """
    # Assuming you have a function to get user details
    user = db.collection("users").document(uid).get()
    if user.exists:
        user_data = user.to_dict()
        connectAccountId = user_data.get("connectAccountId")
        if connectAccountId: return connectAccountId
    return None

def convertCustomizerItems(name, platformOrderId, productId, variantId, variation, quantity, price, placementsData:dict, shop:Shop, blankVariantId = None, variant = {}):
    data = placementsData
    placementDetails= dict(data.get("placementDetails"))
    blankProductId = variation.get("blankProductId")
    variantType = placementDetails.get(blankProductId, {}).get("variantType")
    if not variantType: variantType = "color"
    canvasImages = placementDetails.get(blankProductId, {}).get("canvasImages", {})
    printImages = []
    color = variation.get("color")
    for key, canvasImage in canvasImages.items():
        for placement, printImage in canvasImage.items():
            printImages.append(
                    dict(
                        id = printImage.get("id"),
                        placement = placement,
                        url = printImage.get("url"),
                        name = printImage.get("name"),
                        type="printing",
                        **{variantType: key}
                    )
            )
    mockImages = []
    previewImages = placementDetails.get(blankProductId, {}).get("previewImages", {})
    for key, placementPreviews in previewImages.items():
        for placement, img in placementPreviews.items():
            mockImages.append(
                dict(
                    id = img.get("id"),
                    url = img.get("url"),
                    name = img.get("name"),
                    placement = placement,
                    type="preview",
                    **{variantType: key}
                )
            )
    variantType = placementDetails.get(blankProductId, {}).get("variantType", "color")
    thisItemPrintImages = [i for i in printImages if i.get(variantType) == variation.get(variantType)]
    if len(thisItemPrintImages) == 0:  thisItemPrintImages = [i for i in printImages if i.get(variantType) == "default"]
    thisItemMockImages = [i for i in mockImages if i.get(variantType) == variation.get(variantType)]
    if len(thisItemMockImages) == 0:  thisItemMockImages = [i for i in mockImages if i.get(variantType) == "default"]
    if not blankVariantId:
        blankVariantId = variant.get("blankVariantId") if variant.get("blankVariantId")  else variant.get("id")
    # blankVariantId = variant.get("blankVariantId") if variant.get("blankVariantId")  else variant.get("id")
    platformOrderItemId =str(datetime.now().timestamp())
    convertedOrderItem = convertedOrderItem = convertOrderItem(
                        uid = shop.uid,
                        platformId = "13",
                        enterpriseId=shop.enterpriseId,
                        platformOrderItemId= platformOrderItemId,
                        platformOrderId = platformOrderId,
                        shopId=shop.id,
                        cancelled=False,
                        createdAt= datetime.now(),
                        updatedAt= datetime.now(),
                        name= name,
                        platformProductId= productId,
                        price= price,
                        quantity= quantity,
                        shipped= False,
                        variantId=variantId,
                        images=thisItemMockImages,
                        productMapping = dict(
                                    printOnDemand=True, 
                                    ignored=False,
                                    decorationType=data.get("product").get("decorationType"),
                                ),
                        variantMapping=dict(
                            blankProductId=blankProductId,
                            blankVariantId = blankVariantId,
                            images=thisItemPrintImages,
                            placements=[i.get("placement") for i in thisItemPrintImages],
            ))
    return convertedOrderItem

def completeOrder(paymentIntentId):
    ref = db.collection("stripeCheckouts").document(paymentIntentId)
    stripeCheckout = ref.get()
    if stripeCheckout.exists:
        stripeCheckout = stripeCheckout.to_dict()
        products = stripeCheckout.get("products", [])
        shippingAddress = stripeCheckout.get("shippingAddress")
        if not shippingAddress: return "No shipping address", 400
        uid, enterpriseId, shopId = (
            stripeCheckout.get("uid"),
            stripeCheckout.get("enterpriseId"),
            stripeCheckout.get("shopId"),
        )
        platformOrderId = str(int(datetime.now().timestamp()))
        # 4 digit random order number
        orderNumber = str(random.randint(1000, 9999))
        shop = Shop.get(shopId)
        stripeCreds = getStripeCreds("cfbZh6XFBG3usCcUwpRE")
        apiKey = stripeCreds.get("apiSecret")
        publishableKey = stripeCreds.get("apiKey")
        if stripeCheckout.get("hostname") in [
            "spstore.mycart.me",
            "christmas.mycart.me",
        ]:
            apiKey = stripeCreds.get("apiSecretTest")
            publishableKey = stripeCreds.get("apiKeyTest")
        shippingAddress = Address(
            name=shippingAddress.get("name"),
            address1=shippingAddress.get("address1"),
            address2=shippingAddress.get("address2"),
            zip=shippingAddress.get("zip"),
            city=shippingAddress.get("city"),
            state=shippingAddress.get("state"),
            country=shippingAddress.get("country"),
            countryCode=shippingAddress.get("country"),
        )
        convertedOrderItems = []
        totalPrice = 0
        tax, subtotal, total, shippingCost = (
            stripeCheckout.get("tax"),
            stripeCheckout.get("subtotal"),
            stripeCheckout.get("totalCost"),
            stripeCheckout.get("shippingCost"),
        )
        for p in products:
            customizationId = p.get("customizationId")
            customizationDetails = db.document(f"popupStoreCartPlacements/{customizationId}").get().to_dict()
            if customizationDetails:
                product = customizationDetails.get("product")
                variation = customizationDetails.get("variations")[0]
                productId, quantity, variantId = (
                    product.get("id"),
                    p.get("quantity"),
                    variation.get("id"),
                )
                print("CUSTOMIZED",customizationDetails)
                convertedOrderItem = convertCustomizerItems(
                        name=product.get("name"),
                        platformOrderId=platformOrderId,
                        productId=productId,
                        variantId=variantId,
                        # variant=variant,
                        variation=variation,
                        quantity=quantity,
                        price=variation.get("price"),
                        placementsData=customizationDetails,
                        shop=shop,
                        blankVariantId=variation.get("id"),
                    ) 
            else: 
                variant = Variant.get(productId, variantId).to_dict()
                convertedOrderItem = convertOrderItem(
                enterpriseId=enterpriseId,
                uid=uid,
                platformOrderItemId=products.index(p),
                platformOrderId=platformOrderId,
                platformProductId=productId,
                platformId=shop.platformId,
                shopId=shop.id,
                name=product.get("name"),
                image=(
                    Image(url=product.get("images")[0].get("url")).to_dict()
                    if product.get("images")
                    else None
                ),
                price=variant.get("price"),
                subtotal=variant.get("price") * quantity,
                discount=0,
                total=variant.get("price") * quantity,
                tax=0,
                variantId=variantId,
                productId=productId,
                quantity=quantity,
                variant=variant,
            )
            totalPrice += convertedOrderItem.get("total", 0)
            convertedOrderItems.append(convertedOrderItem)
        convertedOrder = convertOrder(
            uid=uid,
            enterpriseId=enterpriseId,
            platformOrderId=platformOrderId,
            platformId=shop.platformId,
            shopId=shop.id,
            shipped=False,
            cancelled=False,
            currencyCode="USD",
            draft=False,
            totalDiscount=0,
            totalPrice=subtotal,
            totalTax=tax,
            shippingCost=shippingCost,
            grandTotal=total,
            shippingAddress=shippingAddress.to_dict(),
            shopName=shop.name,
            orderNumber=orderNumber,
            metadata=stripeCheckout,
            createdAt=datetime.now(),
            updatedAt=datetime.now(),
        )
        if convertedOrderItems:
            orderId = saveOrder(convertedOrder, convertedOrderItems)
            ref.update(
                dict(
                    status="completed",
                    orderId=orderId,
                    orderNumber=orderNumber,
                    completedAt=datetime.now(),
                )
            )
            return f"Order Created - {orderId}", 200
        # try:
        #     orderCost = getPopupStoreOrderCost(orderId, uid)
        #     if orderCost:
        #         orderTotal = total
        #         platform_fee_cents = int(orderTotal * 0.03 * 100)
        #         orderCost = (
        #             orderCost.get("totalCost") if orderCost.get("totalCost") else total
        #         )
        #         storeOwnerAmount = orderTotal - orderCost
        #         store_owner_account = getUserConnectAccountId(shop.uid)
        #         fulfiller_account = getAdminConnectAccountId(shop.enterpriseId)
        #         if store_owner_account and fulfiller_account:
        #             fulfiller_amount = int(orderCost * 100) - platform_fee_cents
        #             distribute_payments(
        #                 apiKey=apiKey,
        #                 store_owner_amount=int(storeOwnerAmount * 100),
        #                 store_owner_account=store_owner_account,
        #                 fulfiller_account=fulfiller_account,
        #                 fulfiller_amount=fulfiller_amount,
        #             )
        #             saveConnectTransaction(
        #                 accountId=store_owner_account,
        #                 amount=total,
        #             )
        #             updateStripeConnectWallet(
        #                 accountId=store_owner_account, amount=total, type="credit"
        #             )
        #             saveConnectTransaction(
        #                 accountId=fulfiller_account,
        #                 amount=orderCost,
        #             )
        #             updateStripeConnectWallet(
        #                 accountId=fulfiller_account, amount=orderCost, type="credit"
        #             )
        #     else:
        #         print("Order cost calculation failed", 400)
        # except Exception as e:
        #     print(e)
        #     return "Error in calculating order cost", 400
    return "Session not found", 200


def getUserConnectAccountId(uid):
    """
    Get Stripe Account ID from user ID
    """
    user = db.collection("users").document(uid).get()
    if user.exists:
        user = user.to_dict()
        stripeAccountId = user.get("connectAccountId")
        if stripeAccountId:
            return stripeAccountId
    return None

# print(completeOrder("pi_3RQt72Kc34kmwhxF0dhF9Tyw"))

def getAdminConnectAccountId(enterpriseId):
    """
    Get Stripe Account ID from user ID
    """
    enterprise = db.collection("enterprises").document(enterpriseId).get()
    uid = enterprise.get("uid")
    user = db.collection("users").document(uid).get()
    if user.exists:
        user = user.to_dict()
        stripeAccountId = user.get("connectAccountId")
        if stripeAccountId:
            return stripeAccountId
    return None


def saveConnectTransaction(accountId, amount=0, type="credit", metadata: dict = {}):
    transactionId = str(int(datetime.now().timestamp()))
    ref = db.document("stripeConnectTransactions/" + transactionId)
    transaction = dict(
        id=transactionId,
        accountId=accountId,
        amount=amount,
        createdAt=datetime.now(),
        updatedAt=datetime.now(),
        type=type,
        **metadata,
    )
    ref.set(transaction)
    return transaction


def updateStripeConnectWallet(accountId, amount, type="credit"):
    walletRef = db.document(f"stripeConnectAccounts/{accountId}").get()
    if walletRef.exists:
        wallet = walletRef.to_dict()
        balance = wallet.get("balance", 0)
        walletRef.reference.update(
            dict(
                balance=(
                    round(float(balance + amount), 2)
                    if type == "credit"
                    else round(float(balance - amount), 2)
                ),
                updatedAt=datetime.now(),
            )
        )
    else:
        walletRef.reference.set(
            dict(
                createdAt=datetime.now(),
                updatedAt=datetime.now(),
                balance=amount if type == "credit" else 0,
            )
        )


def getStripeConnectWallet(accountId):
    """
    Get Stripe Account ID from user ID
    """
    walletRef = db.document(f"stripeConnectAccounts/{accountId}").get()
    if walletRef.exists:
        wallet = walletRef.to_dict()
        return wallet
    return None


def getPopupStoreOrderCost(orderId, uid):
    import requests

    url = f"https://riverr-enterprise-user.uc.r.appspot.com/orders/{orderId}/cost"

    # url = f"http://localhost:4000/orders/{orderId}/cost"

    payload = {}
    headers = {"x-uid": uid}

    response = requests.request("GET", url, headers=headers, data=payload)
    if response.status_code == 200:
        return response.json()
    return None


def create_payment_intent(
    amount_in_cents,
    platform_fee_cents,
    store_owner_account,
    fulfiller_account,
    fulfiller_fee_cents,
):
    try:
        # Create PaymentIntent with platform fee
        payment_intent = stripe.PaymentIntent.create(
            amount=amount_in_cents,  # Total amount in cents
            currency="usd",
            payment_method_types=["card"],
            transfer_data={
                "destination": store_owner_account,  # Store owner's Connected Account
            },
            application_fee_amount=platform_fee_cents,  # Platform fee
        )

        # Create a separate transfer for the fulfiller fee
        stripe.Transfer.create(
            amount=fulfiller_fee_cents,  # Fulfiller's share
            currency="usd",
            destination=fulfiller_account,  # Fulfiller's Connected Account
            description="Fulfiller fee transfer",
        )

        print("PaymentIntent created:", payment_intent)
        return payment_intent
    except stripe.error.StripeError as e:
        print("Error:", e.user_message)
        return None


# # Example usage
# if __name__ == "__main__":
#     total_amount = 10000  # $100.00
#     platform_fee = 1000  # $10.00
#     fulfiller_fee = 2000  # $20.00
#     store_owner_account = "acct_store_owner"  # Replace with actual account ID
#     fulfiller_account = "acct_fulfiller"  # Replace with actual account ID

#     create_payment_intent(total_amount, platform_fee, store_owner_account, fulfiller_account, fulfiller_fee)



def create_payment_intent(
    amount_in_cents,
    platform_fee_cents,
    store_owner_account,
    fulfiller_account,
    fulfiller_fee_cents,
):
    try:
        # Create PaymentIntent with platform fee
        payment_intent = stripe.PaymentIntent.create(
            amount=amount_in_cents,  # Total amount in cents
            currency="usd",
            payment_method_types=["card"],
            transfer_data={
                "destination": store_owner_account,  # Store owner's Connected Account
            },
            application_fee_amount=platform_fee_cents,  # Platform fee
        )

        # Create a separate transfer for the fulfiller fee
        stripe.Transfer.create(
            amount=fulfiller_fee_cents,  # Fulfiller's share
            currency="usd",
            destination=fulfiller_account,  # Fulfiller's Connected Account
            description="Fulfiller fee transfer",
        )

        print("PaymentIntent created:", payment_intent)
        return payment_intent
    except stripe.error.StripeError as e:
        print("Error:", e.user_message)
        return None


def distribute_payments(
    apiKey, store_owner_amount, store_owner_account, fulfiller_amount, fulfiller_account
):
    try:
        stripe.api_key = apiKey
        # Transfer to the store owner
        stripe.Transfer.create(
            amount=store_owner_amount,  # 70% of the total to the store owner
            currency="usd",
            destination=store_owner_account,
            description="Store owner's payment",
        )

        # Transfer to the fulfiller
        stripe.Transfer.create(
            amount=fulfiller_amount,  # 20% of the total to the fulfiller
            currency="usd",
            destination=fulfiller_account,
            description="Fulfiller's payment",
        )

        # # Platform fee is retained
        # stripe.Transfer.create(
        #     amount=platform_fee,  # Platform fee (remaining 10%)
        #     currency="usd",
        #     destination=platform_account,
        #     description="Platform fee",
        # )

        print("Payments distributed successfully!")
    except stripe.error.StripeError as e:
        print("Error distributing payments:", e.user_message)


import easypost

from V2.functions.Applications.main import Application


def getEasypostRates(
    apiKey: str, fromAddress: Address, toAddress: Address, parcel: dict
):
    rates = []
    try:
        easypost.api_key = apiKey
        fromAddress = dict(
            name=fromAddress.name,
            street1=fromAddress.address1,
            street2=fromAddress.address2,
            state=fromAddress.state,
            city=fromAddress.city,
            zip=fromAddress.zip,
            country=fromAddress.country,
            phone=fromAddress.phone,
        )
        toAddress = dict(
            name=toAddress.name,
            street1=toAddress.address1,
            street2=toAddress.address2,
            city=toAddress.city,
            state=toAddress.state,
            zip=toAddress.zip,
            country=toAddress.country,
            phone=toAddress.phone if toAddress.phone else fromAddress.get("phone"),
        )
        parcel = dict(
            length=parcel.get("length"),
            width=parcel.get("width"),
            height=parcel.get("height"),
            weight=parcel.get("weight"),
        )
        shipment = easypost.Shipment.create(
            to_address=toAddress,
            from_address=fromAddress,
            parcel=parcel,
            options=dict(label_size="4x6"),
            # carrier_accounts=[],
            address_validation_level="0",
            customs_info=easypost.CustomsInfo.create(
                customs_items=[
                    easypost.CustomsItem.create(
                        description="Clothing",
                        quantity="1",
                        weight=parcel.get("weight"),
                        value=1,
                        origin_country=fromAddress.get("country"),
                        hs_tariff_number="610910",
                    )
                ],
                eel_pfc="NOEEI 30.37(a)",
                contents_type="merchandise",
                restriction_type="none",
                restriction_comments="none",
                non_delivery_option="return",
                customs_certify="true",
                customs_signer=None,
                contents_explanation="",
            ),
        )
        rates = shipment.get("rates")
        if not rates:
            raise API_Error("No rates available", 500)
        rateNames = {
            "GroundAdvantage": "Ground",
        }
        return [
            dict(
                id=rate.get("id"),
                name=rateNames.get(rate.get("service"), rate.get("service")),
                carrierId=rate.get("carrier_account_id"),
                carrierName=rate.get("carrier"),
                cost=round(float(rate.get("rate")), 2),
                deliveryDays=rate.get("delivery_days"),
                shipmentId=rate.get("shipment_id"),
                platformId="EASYPOST",
                platformName="EasyPost",
                serviceId=rate.get("service"),
            )
            for rate in rates
            if rate.get("carrier") == "USPS"
        ]
    except Exception as e:
        # print traceback
        import traceback

        trace = traceback.format_exc()
        raise API_Error(str(e), 500)
    return []


def filtered_and_update_rate_names(rates, options):
    updated_rates = []

    for rate in rates:
        for option in options:
            if (
                rate["carrierName"] in option["carrierName"]
                and option["serviceId"] == rate["serviceId"]
            ):
                rate = {**rate, "name": option["name"]}
                updated_rates.append(rate)
                break

    return updated_rates


def fetchShippingRates(params: Params):
    enterpriseId = params.currentUser.enterpriseId
    shippingAddress = Address.from_dict(params.args.get("shippingAddress"))
    # products = params.args.get("products")
    weight = params.args.get("weight", 5)
    dimensions = params.args.get("dimensions", {})
    parcel = dict(
        height=dimensions.get("height", 2),
        weight=weight,
        length=dimensions.get("length", 12),
        width=dimensions.get("width", 15),
    )
    app = Application.get("EASYPOST" + enterpriseId, type="shipping")
    fromAddress = Address.getDefaultAddress(enterpriseId, uid=params.currentUser.uid)
    rates = getEasypostRates(app.apiKey, fromAddress, shippingAddress, parcel)
    popupStoreShippingOptionsRef = (
        db.collection("enterprises")
        .document(enterpriseId)
        .collection("popupStoreShippingOptions")
        .get()
    )

    if popupStoreShippingOptionsRef:
        popupStoreShippingOptions = [
            doc.to_dict() for doc in popupStoreShippingOptionsRef
        ]
        updated_rates = filtered_and_update_rate_names(rates, popupStoreShippingOptions)
        if updated_rates: return dict(
                rates=updated_rates,
            )
    return dict(rates=rates)


def getPopupStoreOrderNumber(shopId):
    ref = db.document("shopsCredentials/" + shopId).get()


def getPayouts(params: Params):
    currentUser = params.currentUser
    connectAccountId = currentUser.connectAccountId
    wallet = getStripeConnectWallet(connectAccountId)
    balance = wallet.get("balance", 0)
    return {
        "payouts": [],
        "balance": {
            "available": {"amount": balance, "currency": "usd"},
            "pending": {"amount": 0, "currency": "usd"},
        },
        "next_payout_date": {"interval": "weekly", "weekly_anchor": "monday"},
    }


# d = completeOrder("pi_3RBpO7Kc34kmwhxF1fdSInpI")
# print(d)


def popStoreCustomizer(params: Params):
    product, variations, placementDetails = (
        params.args.get("product").get("productDetails"),
        params.args.get("product").get("variations"),
        params.args.get("placementDetails"),
    )
    uid, enterpriseId = params.currentUser.get("uid"), params.currentUser.get("enterpriseId")
    hostname = params.hostname
    shop = getPopupStore(hostname)
    shopId = shop.id
    customizationId = str(int(datetime.now().timestamp()))
    productId = product.get("id")+customizationId
    type = product.get("type")
    ref = db.document(f"popupStoreCartPlacements/{customizationId}").set(
        dict(
            id=customizationId,
            placementDetails=placementDetails,
            variations=variations,
            product=product,
            parentProductId=productId,
            enterpriseId=enterpriseId,
            uid=uid,
            createdAt=SERVER_TIMESTAMP,
            updatedAt=SERVER_TIMESTAMP,
            shopId=shopId,
            type=type,
        )
    )
    return dict(
        productId=productId,
        variants=[dict(
            id=v.get("id"),
            sku=v.get("id"),
            name=product.get("name"),
            price=v.get("price"),
        ) for v in variations],
        customizationId=customizationId,
    )
