import base64
import hashlib
import hmac

from flask import Blueprint, Response, abort, request

from functions.Applications import getAppCredentials
from functions.Response import sendResponse
from functions.Shopify import Auth, Fulfillment, Orders, Products
from functions.Shopify.Charge import confirmCharge, createRecurringCharge
from functions.Shops import getShopById

shopifyBlueprint = Blueprint("shopify", __name__)

@shopifyBlueprint.route("/auth")
def auth():
    return sendResponse(Auth.shopifyAuth, request, authRequired=False)

@shopifyBlueprint.get("/auth/<id>")
def directAuth(id):
    args = request.args.to_dict()
    return Auth.shopifyDirectAuth(dict(id=id, **args))

@shopifyBlueprint.route("/anonymous-auth")
def anonymousAuth():
    return sendResponse(Auth.anonyAuth, request, authRequired=False)

@shopifyBlueprint.post("/anonymous-token")
def anonymousToken():
    return sendResponse(Auth.anonyToken, request, authRequired=False)

@shopifyBlueprint.post("/token")
def token():
    return sendResponse(Auth.anonyToken, request)

@shopifyBlueprint.post("/cart-placements")
def shopifyCustomizer():
    return sendResponse(Products.shopifyCustomizer, request)

@shopifyBlueprint.route("/products")
def products():
    return sendResponse(Products.updateAllProducts, request, authRequired=False)

@shopifyBlueprint.route("/orders")
def orders():
    return sendResponse(Orders.updateAllOrders, request, authRequired=False)

@shopifyBlueprint.route("/pub-sub/orders")
def pubsubOrders():
    return sendResponse(Orders.acceptPubsubRequest, request, authRequired=False)
    
# @shopifyBlueprint.post("/fulfillment-service")
# def createFulfillmentService():
#     return sendResponse(Fulfillment.createFulfillmentService, request)

@shopifyBlueprint.post("/<enterpriseId>/cdr")
def customDataRequest(enterpriseId):
    app = getAppCredentials("2"+enterpriseId)
    data = request.get_data()
    verified = verify_webhook(app.get("apiSecret"),data, request.headers.get('X-Shopify-Hmac-SHA256'))
    if not verified:
        return Response("Webhook verification failed.",status=401)
    return sendResponse(Auth.customDataRequest, request, authRequired=False)

@shopifyBlueprint.post("/<enterpriseId>/cde")
def customersRedact(enterpriseId):
    app = getAppCredentials("2"+enterpriseId)
    data = request.get_data()
    verified = verify_webhook(app.get("apiSecret"),data, request.headers.get('X-Shopify-Hmac-SHA256'))
    if not verified:
        return Response("Webhook verification failed.",status=401)
    return sendResponse(Auth.customersRedact, request, authRequired=False)

@shopifyBlueprint.post("/<enterpriseId>/sde")
def shopRedact(enterpriseId):
    app = getAppCredentials("2"+enterpriseId)
    data = request.get_data()
    print(data)
    verified = verify_webhook(app.get("apiSecret"),data,request.headers.get('X-Shopify-Hmac-SHA256'))
    if not verified:
        return Response("Webhook verification failed.",status=401)
    return sendResponse(Auth.shopRedact, request, authRequired=False)

@shopifyBlueprint.post("/fulfillment/fulfillment_order_notification")
def fulfillmentRequest():
    return sendResponse(Orders.fulfillmentRequest, request, authRequired=False)

@shopifyBlueprint.post("/fulfillment/connect_item_location")
def connectProductToLocationAfterMapping():
    return sendResponse(Products.connectProductToLocationAfterMapping, request)
    
@shopifyBlueprint.post("/webhooks/orders")
def ordersWebhook():
    return sendResponse(Orders.orderWebhook, request)

@shopifyBlueprint.post("/webhooks/<shopId>/orders")
def ordersWebhookEvent(shopId):
    data = request.get_data()
    shop = getShopById(shopId)
    appId = shop.get("appId")
    app = getAppCredentials(appId)
    verified = verify_webhook(app.get("apiSecret"),data, request.headers.get('X-Shopify-Hmac-SHA256'))
    if not verified:
        abort(401)
    return sendResponse(Orders.ordersWebhookEvent, request,id=shopId, authRequired=False)

@shopifyBlueprint.post("/subscription")
def subscription():
    return sendResponse(createRecurringCharge, request)

@shopifyBlueprint.post("/confirm-subscription")
def confirmSubscription():
    return sendResponse(confirmCharge, request)

def verify_webhook(apiSecret, data, hmac_header):
    digest = hmac.new(apiSecret.encode('utf-8'),data, hashlib.sha256).digest()
    computed_hmac = base64.b64encode(digest)
    return hmac.compare_digest(computed_hmac, str(hmac_header).encode('utf-8'))