from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from django.http import HttpResponse

from rest_framework import generics
from rest_framework.response import Response
from rest_framework.views import APIView
from drf_spectacular.utils import extend_schema
import os
import logging

from .models import StripeModel
from commerce.models import Order, Payment

logger = logging.getLogger(__name__)

import stripe
stripe.api_key = os.getenv("STRIPE_SECRET_KEY")

class StripeWebhook(APIView):
    @extend_schema(
        tags=["stripe"],
    )
    def post(self, request):
        payload = request.body
        sig_header = request.META['HTTP_STRIPE_SIGNATURE']

        try:
            #build stripe event (api call)
            event = stripe.Webhook.construct_event(
                payload, sig_header, os.getenv("STRIPE_WEBHOOK_SECRET")
            )

        except ValueError as e:
            # TODO: doupravit error handling, dodělat v modelu možnost pro uložení chyby a status ERROR
            logger.error(f"Invalid payload: {e}")
            return HttpResponse(status=400)
        
        except stripe.error as e:
            # stripe error
            logger.error(f"Stripe error: {e}")
            return HttpResponse(status=400)
        

        session = event['data']['object']


        # ZAPLACENO
        if event['type'] == 'checkout.session.completed':
            
            stripe_transaction = StripeModel.objects.get(stripe_session_id=session.id)

            if stripe_transaction:
                stripe_transaction.paid()

                logger.info(f"Transaction {stripe_transaction.id} marked as paid.")

            else:
                logger.warning(f"No transaction found for session ID: {session.id}")

        # EXPIRACE (zrušení objednávky) uživatel nezaplatil do 24 hodin!
        elif event['type'] == 'checkout.session.expired':
            order = Order.objects.get(payment=Payment.objects.get(stripe=StripeModel.objects.get(stripe_session_id=session.id)))
            order.status = Order.STATUS_CHOICES.CANCELLED
            order.save()

        elif event['type'] == 'payment_intent.payment_failed':
            #nothing to do for now
            pass

        # REFUND POTVRZEN
        elif event['type'] == 'payment_intent.refunded':
            session = event['data']['object']
            stripe_transaction = StripeModel.objects.get(stripe_payment_intent=session.id)

            if stripe_transaction:
                stripe_transaction.refund_confirmed()

                logger.info(f"Transaction {stripe_transaction.id} marked as refunded.")
