""" Amazon FPS integration,
    currently not used. due to issues with Taxes """
import urlparse
import urllib
import datetime
import time
import logging
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.core.urlresolvers import reverse
from django.http import HttpResponseForbidden, HttpResponseRedirect, HttpResponse

from billing.integrations.amazon_fps_integration import (
    AmazonFpsIntegration as Integration,
)
from billing.models import AmazonFPSResponse
from billing.signals import transaction_was_successful, transaction_was_unsuccessful

from store_order.models import Order, OrderPayment
from cart import cart

csrf_exempt_m = method_decorator(csrf_exempt)
require_POST_m = method_decorator(require_POST)

LOGGER = logging.getLogger("fps_integration")


class FpsIntegration(Integration):
    @csrf_exempt_m
    @require_POST_m
    def fps_ipn_handler(self, request):
        LOGGER.debug("In fps_ipn_handler")
        uri = request.build_absolute_uri()
        parsed_url = urlparse.urlparse(uri)
        LOGGER.debug("[fps_ipn_handler] verify signiture")
        v_resp = self.fps_connection.verify_signature(
            UrlEndPoint="%s://%s%s"
            % (parsed_url.scheme, parsed_url.netloc, parsed_url.path),
            HttpParameters=request.raw_post_data,
        )
        LOGGER.debug("[fps_ipn_handler] v_resp = ".format(v_resp))
        LOGGER.debug(
            "[fps_ipn_handler] v_resp.VerifySignatureResult = ".format(
                v_resp.VerifySignatureResult
            )
        )
        LOGGER.debug(
            "[fps_ipn_handler] v_resp.VerifySignatureResult.VerificationStatus = ".format(
                v_resp.VerifySignatureResult.VerificationStatus
            )
        )
        if not v_resp.VerifySignatureResult.VerificationStatus == "Success":
            LOGGER.debug("[fps_ipn_handler]  Signature bad")
            return HttpResponseForbidden()

        LOGGER.debug("[fps_ipn_handler]  Signature good")
        data = dict(map(lambda x: x.split("="), request.raw_post_data.split("&")))
        LOGGER.debug("[fps_ipn_handler]  data: {0}".format(data))
        for (key, val) in data.iteritems():
            data[key] = urllib.unquote_plus(val)
        if AmazonFPSResponse.objects.filter(
            transactionId=data["transactionId"]
        ).count():
            LOGGER.debug("[fps_ipn_handler]  have an object already")
            resp = AmazonFPSResponse.objects.get(transactionId=data["transactionId"])
        else:
            LOGGER.debug("[fps_ipn_handler]  no object create one")
            resp = AmazonFPSResponse()
        for (key, val) in data.iteritems():
            attr_exists = hasattr(resp, key)
            if attr_exists and not callable(getattr(resp, key, None)):
                if key == "transactionDate":
                    # TODO: add timezone info .gets this RuntimeWarning: DateTimeField received a naive datetime (2013-02-03 10:58:51) while time zone support is active.
                    val = datetime.datetime(*time.localtime(float(val))[:6])
                setattr(resp, key, val)
        resp.save()
        LOGGER.debug("[fps_ipn_handler]  saved object")
        if resp.statusCode == "Success":
            LOGGER.debug("[fps_ipn_handler]  success")
            transaction_was_successful.send(
                sender=self.__class__, type=data["operation"], response=resp
            )
        else:
            LOGGER.debug(
                "[fps_ipn_handler]  not success it is {0}".format(resp.statusCode)
            )
            if not "Pending" in resp.statusCode:
                LOGGER.debug("[fps_ipn_handler] send unsuccessful signal")
                transaction_was_unsuccessful.send(
                    sender=self.__class__, type=data["operation"], response=resp
                )

        # Associate the amazon payment with our order from before.
        # TODO: this needs to be fully tested.. all scenerios
        # new payments and updates.
        LOGGER.debug("[fps_ipn_handler]  add info to Order ")
        try:
            LOGGER.debug("Cart_id = {0}".format(resp.callerReference))
            order = Order.objects.get(cart_id=resp.callerReference)
            try:
                order_payment = order.orderpayment
            except OrderPayment.DoesNotExist:
                LOGGER.debug("Order_payment does't exist add one")
                order_payment = OrderPayment()
                order.orderpayment = order_payment

            LOGGER.debug("order_payment = {0}".format(order_payment))

            try:
                amazon_payment = order_payment.amazon_payment
                LOGGER.debug(
                    "There is an amazon_payment already {0}".format(amazon_payment)
                )
                if not amazon_payment:
                    LOGGER.debug("Amazon payment is null, need to set it.")
                    order_payment.amazon_payment = resp
            except AmazonFPSResponse.DoesNotExist:
                LOGGER.debug("amazon_payment does't exist add one")
                order_payment.amazon_payment = resp

            LOGGER.debug("Save order payment")
            order_payment.save()
            LOGGER.debug("Set order status to submitted")
            order.status = Order.SUBMITTED
            # TODO: Make sure status is set correctly.
            order.save()
        except Exception as e:
            # TODO log error, send email.
            LOGGER.debug("Error = {0}".format(e))

        # Return a HttpResponse to prevent django from complaining
        LOGGER.debug("[fps_ipn_handler]  Done")
        return HttpResponse(resp.statusCode)

    def transaction(self, request):
        """Ideally at this method, you will check the
        caller reference against a user id or uniquely
        identifiable attribute (if you are already not
        using it as the caller reference) and the type
        of transaction (either pay, reserve etc). For
        the sake of the example, we assume all the users
        get charged $100"""

        """
        {'status': 'SC',
        'city': 'Dallas',
        'signatureVersion': '2',
        'zip': '73933',
        'tokenID': 'F3B8EXIKM4RMLDLRDIHH3LGPTSLAMHTPJMQBEUBCFH24HAAZ339CSD2S8RR9LNPF',
        'country': 'United+States',
        'signature': 'Wc038ij3U0ZmUmKgiFq455WQPz0q7D9TTfUsxNx8WC6Rk%2FGBpGEiFb4gSnQBxY437oAKqEgoaVMF%0AVoWaKw%2Fmp0b88N%2BQpW048l%2FFbgaWr%2FSz3Vs5AamL0JrDfJ7nd3iF3%2BtPU3gmG4D2qfTwBHu%2FQlLk%0A3bHukecNPRpcmPo1jJQ%3D',
        'state': 'TX',
        'certificateUrl': 'https%3A%2F%2Ffps.sandbox.amazonaws.com%2Fcerts%2F090911%2FPKICert.pem%3FrequestId%3D1mmly3b6mqxve2fuq5vof9sb27gj2nbgt4e0ipj3ff5sxbmo1j',
        'expiry': '01%2F2015',
        'signatureMethod': 'RSA-SHA1',
        'callerReference': '366dcf11-6111-4efb-ac1a-0d0f906cbc62',
        'addressLine2': 'Apt.+2B+-+92+DfkR',
        'addressLine1': '123+Main+St%2C+200+EduFeG',
        'phoneNumber': '5551234567',
        'addressName': 'Ken+Cochrane'}
        """

        request_url = request.build_absolute_uri()
        LOGGER.debug("request_url = {0}".format(request_url))
        parsed_url = urlparse.urlparse(request_url)
        LOGGER.debug("parsed_url = {0}".format(parsed_url))
        query = parsed_url.query
        LOGGER.debug(query)
        # resp = self.purchase(100, data)
        LOGGER.debug("---")
        data = dict(map(lambda x: x.split("="), query.split("&")))
        LOGGER.debug(data)
        LOGGER.debug("---")
        for (key, val) in data.iteritems():
            data[key] = urllib.unquote_plus(val)
        # if AmazonFPSResponse.objects.filter(transactionId=data["transactionId"]).count():
        #     resp = AmazonFPSResponse.objects.get(transactionId=data["transactionId"])
        # else:
        #     resp = AmazonFPSResponse()

        # data['TransactionAmount'] = '100'
        # data['TransactionAmount.Value'] = 1
        LOGGER.debug(data)
        LOGGER.debug("session_key = {0}".format(request.session.session_key))
        shopping_cart = cart.get_cart(request)
        LOGGER.debug("Cart = {0}".format(shopping_cart))
        order = Order.objects.get(cart_id=shopping_cart.cart_id)
        LOGGER.debug("Order = {0}".format(order))

        order.phone = data.get("phoneNumber", None)

        order.shipping_name = data.get("addressName", None)
        order.shipping_address_1 = data.get("addressLine1", None)
        order.shipping_address_2 = data.get("addressLine2", None)
        order.shipping_city = data.get("city", None)
        order.shipping_state = data.get("state", None)
        order.shipping_country = data.get("country", None)
        order.shipping_zip = data.get("zip", None)

        order.billing_name = data.get("addressName", None)
        order.billing_address_1 = data.get("addressLine1", None)
        order.billing_address_2 = data.get("addressLine2", None)
        order.billing_city = data.get("city", None)
        order.billing_state = data.get("state", None)
        order.billing_country = data.get("country", None)
        order.billing_zip = data.get("zip", None)
        order.save()

        # TODO: order.total needs to be more then 0.0 if not, problem.
        resp = self.purchase(order.total, data)

        LOGGER.debug(resp["status"])

        return HttpResponseRedirect(
            "%s?status=%s" % (reverse("checkout_receipt"), resp["status"])
        )
