import json
import hmac
import hashlib
import os
from decimal import Decimal
from django.utils import timezone
from django.views.decorators.csrf import csrf_exempt
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .serializers import PaymentTransactionSerializer
from .models import PaymentTransaction
from .services.payment_service import create_payment, verify_payment
from .services.razorpay_service import create_order, get_active_webhook_secret
from apps.core.events.event_bus import emit_event


class CreateOrderView(APIView):
    def post(self, request):
        data = request.data
        amount = data.get('amount')
        currency = data.get('currency', 'INR')
        user = request.user if request.user.is_authenticated else None

        if not amount:
            return Response({'detail': 'amount required'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            res = create_payment(amount=amount, currency=currency, user=user)
            return Response(res)
        except Exception as exc:
            return Response({'detail': str(exc)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class VerifyPaymentView(APIView):
    def post(self, request):
        data = request.data
        payment_id = data.get('razorpay_payment_id')
        order_id = data.get('razorpay_order_id')
        signature = data.get('razorpay_signature')
        txn_id = data.get('transaction_id')
        if not (payment_id and order_id and signature and txn_id):
            return Response({'detail': 'missing parameters'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            verify_payment(payment_id, order_id, signature, txn_id)
            return Response({'detail': 'verified'})
        except Exception as exc:
            return Response({'detail': str(exc)}, status=status.HTTP_400_BAD_REQUEST)


@csrf_exempt
def razorpay_webhook(request):
    # raw body and signature header
    body = request.body
    signature = request.META.get('HTTP_X_RAZORPAY_SIGNATURE')
    secret = get_active_webhook_secret()

    if not secret or not signature:
        return Response({'detail': 'missing webhook secret or signature'}, status=400)

    # compute HMAC SHA256
    expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, signature):
        return Response({'detail': 'invalid signature'}, status=400)

    payload = json.loads(body.decode('utf-8'))
    # handle event types
    event = payload.get('event')
    try:
        # extract order_id depending on structure
        order_id = None
        if payload.get('payload', {}).get('payment'):
            order_id = payload['payload']['payment']['entity'].get('order_id')

        if not order_id:
            return Response({'detail': 'order_id not found'}, status=400)

        # delegate webhook handling to service if necessary, otherwise use inline logic
        txn = PaymentTransaction.objects.filter(provider_order_id=order_id).first()
        if not txn:
            return Response({'detail': 'transaction not found'}, status=404)

        if event == 'payment.captured':
            txn.status = 'success'
            txn.completed_at = timezone.now()
            txn.save(update_fields=['status', 'completed_at'])
            emit_event('payment_success', {'payment_id': str(txn.id)})
        elif event == 'payment.failed':
            txn.status = 'failed'
            txn.save(update_fields=['status'])

        return Response({'ok': True})
    except Exception:
        return Response({'detail': 'error processing webhook'}, status=500)
