from datetime import date, timedelta
from calendar import monthrange

import stripe
from django.conf import settings
from django.contrib.auth import get_user_model
from django.http import HttpResponse
from rest_framework.permissions import AllowAny
from rest_framework.views import APIView

from verify_trusted.companies.api.serializers import SubscriptionSerializer
from verify_trusted.companies.models import Payment, Subscription

User = get_user_model()

stripe.api_key = settings.STRIPE_API_KEY


class StripeWebhookViewSet(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        payload = request.body
        sig_header = request.META['HTTP_STRIPE_SIGNATURE']
        try:
            event = stripe.Webhook.construct_event(
                payload, sig_header, settings.STRIPE_WEBHOOK_SECRET
            )
            data = event['data']
        except ValueError as e:
            # Invalid payload
            return HttpResponse({'data': e, 'sig_header': sig_header}, status=400)
        except stripe.error.SignatureVerificationError as e:
            # Invalid signature
            return HttpResponse({'data': e, 'sig_header': sig_header}, status=400)
        # if event["type"] in [
        #     "payment_intent.payment_failed",
        #     "payment_intent.canceled",
        # ]:
        #     intent = event['data']['object']
        #     print('Day la session intent %s' % intent)
        #     payment_id = intent['metadata']['payment_id']
        #     payment = Payment.objects.get(id=payment_id)
        #     payment.stripe_status = intent['status']
        #     payment.status = Payment.Status.CANCEL
        #     payment.save()
        #
        # elif event["type"] == "payment_intent.succeeded":
        #     intent = event['data']['object']
        #     print('Day la session intent %s' % intent)
        #     payment_id = intent['metadata']['payment_id']
        #     payment = Payment.objects.get(id=payment_id)
        #     payment.stripe_status = intent['status']
        #     payment.status = Payment.Status.COMPLETE
        #     payment.save()
        data_object = data['object']
        if event["type"] == "invoice.paid":
            try:
                subscription_event = event['data']['object']
                print('Day la session subscription %s' % subscription_event)
                subscription_id = data_object['subscription']
                payment = Payment.objects.get(stripe_id=subscription_id)
                payment.stripe_status = subscription_event['status']
                payment.status = Payment.Status.COMPLETE
                payment.save()

                subscription = Subscription.objects.filter(company=payment.company).first()
                if subscription is None:
                    serializer = SubscriptionSerializer(
                        data={
                            'company': payment.company.id,
                            'payment': payment.id,
                            'due_date': date.today()
                                        + timedelta(days=int(payment.plan.pack)),
                        }
                    )
                    serializer.is_valid(raise_exception=True)
                    serializer.create(serializer.validated_data)
                else:
                    subscription.due_date = date.today() + timedelta(
                        days=int(payment.plan.pack)
                    )
                    subscription.payment = payment
                    subscription.save()
            except Exception as e:
                print(e)
        elif event.type == 'invoice.payment_succeeded':
            if data_object['billing_reason'] == 'subscription_create':
                subscription_id = data_object['subscription']
                payment_intent_id = data_object['payment_intent']
                payment_intent = stripe.PaymentIntent.retrieve(payment_intent_id)
                stripe.Subscription.modify(
                    subscription_id,
                    default_payment_method=payment_intent.payment_method
                )
                subscription_event = data_object['object']
                print('Day la session subscription %s' % subscription_event)
                payment_id = subscription_event['metadata']['payment_id']
                payment = Payment.objects.get(id=payment_id)
                payment.stripe_status = "succeeded"
                payment.status = Payment.Status.COMPLETE
                payment.save()

                subscription = Subscription.objects.filter(company=payment.company).first()
                if subscription is None:
                    serializer = SubscriptionSerializer(
                        data={
                            'company': payment.company.id,
                            'payment': payment.id,
                            'due_date': None,
                        }
                    )
                    serializer.is_valid(raise_exception=True)
                    serializer.create(serializer.validated_data)
                else:

                    subscription.due_date = date.today() + timedelta(
                        days=int(payment.plan.pack)
                    )
                    subscription.payment = payment
                    subscription.save()
                print("Default payment method set for subscription:" + payment_intent.payment_method)
        elif event.type == 'invoice.payment_failed':
            subscription_event = data_object['object']
            payment_id = subscription_event['metadata']['payment_id']
            payment = Payment.objects.get(id=payment_id)
            payment.stripe_status = "FAILED"
            payment.status = Payment.Status.FAILED
            payment.save()

            subscription = Subscription.objects.filter(company=payment.company).first()
            if subscription is None:
                serializer = SubscriptionSerializer(
                    data={
                        'company': payment.company.id,
                        'payment': payment.id,
                        'due_date': date.today()
                                    + timedelta(days=int(payment.plan.pack)),
                    }
                )
                serializer.is_valid(raise_exception=True)
                serializer.create(serializer.validated_data)
            else:
                subscription.due_date = date.today() + timedelta(
                    days=int(payment.plan.pack)
                )
                subscription.payment = payment
                subscription.save()
            print('Invoice payment failed: %s', event.id)

        elif event.type == 'invoice.finalized':
            # If you want to manually send out invoices to your customers
            # or store them locally to reference to avoid hitting Stripe rate limits.
            # print(data)
            print('Invoice finalized: %s', event.id)

        elif event.type == 'customer.subscription.deleted':
            # handle subscription cancelled automatically based
            # upon your subscription settings. Or if the user cancels it.
            # print(data)
            if hasattr(data_object, 'object'):
                d = date.today()
                subscription_event = data_object['object']
                payment_id = subscription_event['metadata']['payment_id']
                payment = Payment.objects.get(id=payment_id)
                subscription = Subscription.objects.filter(company=payment.company).first()
                if subscription is None:
                    subscription.due_date = date(d.year, d.month, monthrange(d.year, d.month)[-1])
                    subscription.payment = payment
                    subscription.save()
            print('Subscription canceled: %s', event.id)
        elif event.type == 'payment_intent.succeeded':
            try:
                intent = event['data']['object']
                print('this is payment_intent.succeeded %s' % intent)
                invoices_id =intent.charges.data[0].invoice
                invoices_status =intent.charges.data[0].status
                if invoices_id and invoices_status=="succeeded":
                    subscription_id = stripe.Invoice.retrieve(invoices_id).subscription
                    payment = Payment.objects.get(stripe_id=subscription_id)
                    payment.stripe_status = invoices_status
                    payment.status = Payment.Status.COMPLETE
                    payment.save()

                    subscription = Subscription.objects.filter(company=payment.company).first()
                    if subscription is None:
                        serializer = SubscriptionSerializer(
                            data={
                                'company': payment.company.id,
                                'payment': payment.id,
                                'due_date': date.today()
                                            + timedelta(days=36500),
                            }
                        )
                        serializer.is_valid(raise_exception=True)
                        serializer.create(serializer.validated_data)
                    else:
                        subscription.due_date = date.today() + timedelta(
                            days=365000
                        )
                        subscription.payment = payment
                        subscription.save()
            except Exception as e:
                print(e)



        else:
            print('Unhandled event type {}'.format(event.type))
            print(data_object)

        # else:
        #     intent = event['data']['object']
        #     payment_id = intent['metadata']['payment_id']
        #     payment = Payment.objects.get(id=payment_id)
        #     payment.stripe_status = intent['status']
        #     payment.save()
        return HttpResponse({'success': True}, status=200)


stripe_webhook_view = StripeWebhookViewSet.as_view()
