
import json
from django.http import JsonResponse
from django.shortcuts import render
from rest_framework import status
from datetime import datetime, timedelta, time
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views import View
from DRIVERZZ_CUSTOMER_APIS import settings
from authentication.auth import verify_token
from rates.models import Daytimes, RateLists, Taxes
from trips.models import Trips
from transactions.models import Transactions
from django.db.models import Q

from .serializers import TripSerializer, TaxSerializer, TripsSerializer


from trips.helpers import total_daytime_minutes 

import razorpay
client = razorpay.Client(auth=(settings.RAZORPAY_KEY_ID, settings.RAZORPAY_KEY_SECRET))


@method_decorator(csrf_exempt, name='dispatch')
class Trip(View):

    def post(self, request):
        user_id = verify_token(request)
        if user_id == None:
            return JsonResponse({'message':"User not login.", 'status':status.HTTP_401_UNAUTHORIZED}, safe=False, status=status.HTTP_401_UNAUTHORIZED)
        else:
            try:
                request_data = json.loads(request.body)
                trip = Trips()
                trip.user_id = user_id
                trip.trip_type = request_data['trip_type']
                trip.pickup_address = request_data['pickup_address']
                trip.pickup_latitude = request_data['pickup_latitude']
                trip.pickup_longitude = request_data['pickup_longitude']
                trip.destination_address = request_data['destination_address']
                trip.destination_latitude = request_data['destination_latitude']
                trip.destination_longitude = request_data['destination_longitude']
                trip.start_date = request_data['start_date']
                trip.start_time = request_data['start_time']
                trip.end_date = request_data['end_date']
                trip.end_time = request_data['end_time']
                trip.station_type = request_data['station_type']
                trip.instructions = request_data['instructions']
                trip.vehicle_model_id = request_data['vehicle_model']
                trip.vehicle_type_id = request_data['vehicle_type']
                trip.transmission_type_id = request_data['transmission_type']
                trip.vehicle_model_name = request_data['vehicle_model_name']
                trip.vehicle_type_name = request_data['vehicle_type_name']
                trip.transmission_type_name = request_data['transmission_type_name']
                trip.amount = request_data['amount']
                trip.net_amount = request_data['net_amount']
                trip.save()
                return JsonResponse({'message': "Trip added successfully", 'status': status.HTTP_200_OK}, safe=False, status=status.HTTP_200_OK)
            except Exception as e:
                print(e)
                return JsonResponse({'message': "Something went wrong. Please try again later.", 'status': status.HTTP_400_BAD_REQUEST}, safe=False, status=status.HTTP_400_BAD_REQUEST)   
                         
    
    def get(self, request):
        user_id = verify_token(request)
        if user_id == None:
            return JsonResponse({'message':"User not login.", 'status':status.HTTP_401_UNAUTHORIZED}, safe=False, status=status.HTTP_401_UNAUTHORIZED)
        else:
            try:
                trip = Trips.objects.get(id = request.GET.get('id'))
                taxes = Taxes.objects.all()
                serializer = TripSerializer(trip, many=False)
                tax_serializer = TaxSerializer(taxes, many=True)
                return JsonResponse({'trip': serializer.data, 'taxes' : tax_serializer.data, 'status': status.HTTP_200_OK}, safe=False, status=status.HTTP_200_OK)
            except Exception as e:
                return JsonResponse({'message': "Something went wrong. Please try again later.", 'status': status.HTTP_400_BAD_REQUEST}, safe=False, status=status.HTTP_400_BAD_REQUEST)                



@method_decorator(csrf_exempt, name='dispatch')
class EditTrip(View):

    def post(self, request, id):
        user_id = verify_token(request)
        if user_id == None:
            return JsonResponse({'message':"User not login.", 'status':status.HTTP_401_UNAUTHORIZED}, safe=False, status=status.HTTP_401_UNAUTHORIZED)
        else:
            try:
                request_data = json.loads(request.body)
                trip = Trips.objects.get(id = id)
                trip.user_id = user_id
                trip.trip_type = request_data['trip_type']
                trip.pickup_address = request_data['pickup_address']
                trip.pickup_latitude = request_data['pickup_latitude']
                trip.pickup_longitude = request_data['pickup_longitude']
                trip.destination_address = request_data['destination_address']
                trip.destination_latitude = request_data['destination_latitude']
                trip.destination_longitude = request_data['destination_longitude']
                trip.edit_start_date = request_data['start_date']
                trip.edit_start_time = request_data['start_time']
                trip.edit_end_date = request_data['end_date']
                trip.edit_end_time = request_data['end_time']
                trip.station_type = request_data['station_type']
                trip.instructions = request_data['instructions']
                trip.vehicle_model_id = request_data['vehicle_model']
                trip.vehicle_type_id = request_data['vehicle_type']
                trip.transmission_type_id = request_data['transmission_type']
                trip.vehicle_model_name = request_data['vehicle_model_name']
                trip.vehicle_type_name = request_data['vehicle_type_name']
                trip.transmission_type_name = request_data['transmission_type_name']
                trip.amount = request_data['amount']
                trip.net_amount = request_data['net_amount']
                trip.save()
                return JsonResponse({'message': "Trip updated successfully", 'status': status.HTTP_200_OK}, safe=False, status=status.HTTP_200_OK)
            except Exception as e:
                print(e)
                return JsonResponse({'message': "Something went wrong. Please try again later.", 'status': status.HTTP_400_BAD_REQUEST}, safe=False, status=status.HTTP_400_BAD_REQUEST)   
                         
    
    



@method_decorator(csrf_exempt, name='dispatch')
class TripList(View):
    def get(self, request):
        user_id = verify_token(request)
        if user_id == None:
            return JsonResponse({'message':"User not login.", 'status':status.HTTP_401_UNAUTHORIZED}, safe=False, status=status.HTTP_401_UNAUTHORIZED)
        else:
            trips = Trips.objects.filter(user_id = user_id)
            trip_status = request.GET.get('status')
            if trip_status == "0":
                trips = trips.filter(status = 2)
            elif trip_status == "1":
                trips = trips.filter(status__lt = 2)
            else:
                trips = trips.filter(status__gt = 2)
            serializer = TripsSerializer(trips, many=True)
            return JsonResponse({'trips': serializer.data, 'status': status.HTTP_200_OK}, safe=False, status=status.HTTP_200_OK)
        


@csrf_exempt
def calculateFare(request):
    request_data = json.loads(request.body)
   
    try:
        amount = 0
        request_data = request_data['trip']
        start_time = datetime.strptime(request_data['start_time'], '%I:%M %p').time()
        end_time = datetime.strptime(request_data['end_time'], '%I:%M %p').time()

        start_timestamp = datetime.strptime(str(request_data['start_date'])+" "+str(start_time), '%Y-%m-%d %H:%M:%S')
        end_timestamp = datetime.strptime(str(request_data['end_date'])+" "+str(end_time), '%Y-%m-%d %H:%M:%S')
        
        time_delta = end_timestamp - start_timestamp
        total_minutes = int((time_delta.total_seconds())/60)
        if total_minutes >= 120:
            pass
        else:
            extra_minutes = 120-total_minutes
            end_timestamp = end_timestamp + timedelta(minutes=extra_minutes)
            time_delta = end_timestamp - start_timestamp
            total_minutes = int((time_delta.total_seconds())/60)
        print("------------------")
        print(total_minutes)
        try:
            
            rate_day = RateLists.objects.filter(duration__gte=total_minutes, station_type = request_data['station_type'], uniform_type = request_data['uniform_type'], day = 0, trip_type = request_data['trip_type']).order_by('duration')
            rate_night = RateLists.objects.filter(duration__gte=total_minutes, station_type = request_data['station_type'], uniform_type = request_data['uniform_type'], day = 1, trip_type = request_data['trip_type']).order_by('duration')
            
            if(len(rate_day) == 0):
                rate_day = RateLists.objects.filter(duration__lt=total_minutes, station_type = request_data['station_type'], uniform_type = request_data['uniform_type'], day = 0, trip_type = request_data['trip_type']).order_by('-duration')
                rate_night = RateLists.objects.filter(duration__lt=total_minutes, station_type = request_data['station_type'], uniform_type = request_data['uniform_type'], day = 1, trip_type = request_data['trip_type']).order_by('-duration')
            
            day_charges = rate_day[0].rate
            night_charges = rate_night[0].rate
            
            day = Daytimes.objects.get(day_type = 0)
            day_start = datetime.strptime(day.start_time, '%I:%M %p').time()


            day = Daytimes.objects.get(day_type = 1)
            day_end = datetime.strptime(day.start_time, '%I:%M %p').time()
            
            day_minutes = 0
            night_minutes = 0
            
            day_start = (day_start.hour, day_start.minute)
            day_end = (day_end.hour, day_end.minute)
            
            day_minutes = total_daytime_minutes(day_start, day_end, start_timestamp, end_timestamp)
            
            if start_timestamp.date() == end_timestamp.date():
                day_minutes = day_minutes / 2 
            
            night_minutes = total_minutes - day_minutes
            
            amount += day_minutes * day_charges
            
            amount += night_minutes * night_charges
            
            taxes = Taxes.objects.all()
            tax_serializer = TaxSerializer(taxes, many=True)
            return JsonResponse({'amount': amount, 'taxes' : tax_serializer.data, 'status': status.HTTP_200_OK}, safe=False, status=status.HTTP_200_OK)
        except Exception as e: 
            print(e)
            return JsonResponse({'amount': 0, 'taxes' : [], 'status': status.HTTP_400_BAD_REQUEST}, safe=False, status=status.HTTP_400_BAD_REQUEST)
        
    except Exception as e:
        print(e)
        return JsonResponse({'amount': 0, 'taxes' : [], 'status': status.HTTP_400_BAD_REQUEST}, safe=False, status=status.HTTP_400_BAD_REQUEST)
    


@csrf_exempt
def paymentHandler(request):
    razorpay_payment_id = request.GET.get('razorpay_payment_id')
    order_id = request.GET.get('razorpay_payment_link_id')
    booking_id = request.GET.get('razorpay_payment_link_reference_id')
    razorpay_payment_link_status = request.GET.get('razorpay_payment_link_status')
    razorpay_signature = request.GET.get('razorpay_signature')
    try:
        result = client.utility.verify_payment_link_signature({
            'payment_link_id': order_id,
            'payment_link_reference_id': booking_id,
            'payment_link_status':razorpay_payment_link_status,
            'razorpay_payment_id': razorpay_payment_id,
            'razorpay_signature': razorpay_signature
        })
    
        if result and razorpay_payment_link_status == 'paid':
            payment_details = client.payment_link.fetch(order_id)
            try:
                transaction = Transactions.objects.get(razorpay_order_id = order_id)
                return render(request, "trips/success.html") 
            except Transactions.DoesNotExist:
                transaction = Transactions()
                try:
                    trip = Trips.objects.get(Q(reference_id = booking_id))
                    transaction.razorpay_order_id = order_id
                    transaction.razorpay_signature = razorpay_signature
                    transaction.razorpay_payment_id = razorpay_payment_id
                    transaction.user_id = trip.user_id
                    transaction.amount = payment_details['amount_paid']
                    trip.payment_status = 1
                    trip.save()
                    transaction.save()
                    if transaction.id:
                        return render(request, "trips/success.html") 
                    else:
                        return render(request, "trips/failed.html") 
                except Exception as e:
                    return render(request, "trips/failed.html") 
    except Exception as e:
        return render(request, "trips/failed.html") 
    


@method_decorator(csrf_exempt, name='dispatch')
class CancelTrip(View):
    def post(self, request):
        user_id = verify_token(request)
        if user_id == None:
            return JsonResponse({'message':"User not login.", 'status':status.HTTP_401_UNAUTHORIZED}, safe=False, status=status.HTTP_401_UNAUTHORIZED)
        else:
            try:
                request_data = json.loads(request.body)
                trip = Trips.objects.get(user_id = user_id, id = request_data['id'])
                trip.status = 4
                trip.save()
                return JsonResponse({'message': "Trip canceled successfully.", 'status': status.HTTP_200_OK}, safe=False, status=status.HTTP_200_OK)
            except Trips.DoesNotExist:
                return JsonResponse({'message': "Something went wrong. Please try again later.", 'status': status.HTTP_400_BAD_REQUEST}, safe=False, status=status.HTTP_400_BAD_REQUEST)   
            # return JsonResponse({'trips': serializer.data, 'status': status.HTTP_200_OK}, safe=False, status=status.HTTP_200_OK)
        