from django.shortcuts import render,redirect
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
#from datetime import  timedelta
from django.utils import timezone
#from django.db.models import Q
from django.db.models import Max
# Create your views here.
from django.http import JsonResponse
from mainApp.models import *
from mainApp.serializers import *
from surgeryApp.serializers import PtSurgeryForInvSerializer
from .models import *
from .serializers import *
############## GENERAL_TOOLS #################
def getClinicId(request):
    try :
        clinicId =  request.session['clinicId'] if 'clinicId' in request.session else request.user.groups.first().clinic.id
    except :
        clinicId = None
    return clinicId
############## END GENERAL_TOOLS #################
############## Finance%Module #################
class PvInvoiceDataApi(APIView):
    #@method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_patients'), login_url='/main/login/'))
    def get(self,request,pv_id):
        if not getClinicId(request) : return redirect('/main/login/')
        p_visits = PatientVisit.objects.filter(id=pv_id)
        nationalities =Nationality.objects.all()
        locations =Location.objects.all()
        cities =City.objects.all()
        number_type_choices = NUMBER_TYPE_TO_DELIVER_CHOICES
        context = {}
        if p_visits:
            p_visit = p_visits[0]
            patient =p_visit.patient
            patients_extra = PatientExtraInfo.objects.filter(patient=patient)
            patient_extra_obj = patients_extra[0] if patients_extra else None
            context.update({"p_visit":p_visit,"patient":patient,"patient_extra":patient_extra_obj})
        else :
            context.update({"p_visit":None,"patient":None,"patient_extra":None})
        context.update({"nationalities":nationalities,"locations":locations,"cities":cities,"number_type_choices":number_type_choices})
        return render(request,"receptionApp/patientPages/pv_invoice.html",context)
    
    def put(self,request,pv_id):
        obj=PatientVisit.objects.get(id=pv_id)
        data = request.data
        data._mutable = True
        user_id = request.user.id
        data.update({"invoice_last_update_by":user_id,"is_e_invoice_request":True})
        serializedObj= PatientVisitForInvSerializer(obj,data=data,partial=True)
        if serializedObj.is_valid():
            serializedObj.save()
            #import pdb
            #pdb.set_trace()
            pve_invoice, created = PvEInvoice.objects.get_or_create(pv=obj)
            #pve_invoice.invoice_serial = data["invoice_serial"]
            # pve_invoice.is_e_invoice_registered =True
            # pve_invoice.registrar_comment =data["invoice_notes"] if data["invoice_notes"] else None
            # pve_invoice.registered_by_id =user_id
            # pve_invoice.registered_at =timezone.now()
            # pve_invoice.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class EInvoicesInProgressApi(APIView):
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        #'pv__patient',  # Join PatientVisit to Patient
        #'pv__patient__PatientExtraInfo_patient'  # Join Patient to PatientExtraInfo
        inprogress_invoices = PvEInvoice.objects.select_related(
        'pv__patient', 
        'pv__patient__PatientExtraInfo_patient'
        ).filter(is_e_invoice_registered=False)
        #patient_ids = inprogress_invoices.values_list('pv__patient_id',flat=True)
        #inprogress_invoices[0].pv.patient.PatientExtraInfo_patient.city.name 
        #patients_extra_info = PatientExtraInfo.objects.filter(patient_id__in=patient_ids)
        return render(request,"receptionApp/xxx/ccc/ddd.html",{
            "inprogress_invoices":inprogress_invoices,
            'activePage':'EInvoicesInProgress'})
    def put(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        data = request.data
        pv_einvoice_id = data["pv_einvoice_id"]
        obj=PvEInvoice.objects.get(id=pv_einvoice_id)
        data._mutable = True
        data.update({"registered_by":request.user.id,"registered_at":timezone.now(),"is_e_invoice_registered":True})
        serializedObj= PvEInvoiceSerializer(obj,data=data,partial=True)
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)#remove from table 
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class EInvoicesInProgressApi(APIView):
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        #'pv__patient',  # Join PatientVisit to Patient
        #'pv__patient__PatientExtraInfo_patient'  # Join Patient to PatientExtraInfo
        inprogress_invoices = PvEInvoice.objects.select_related(
        'pv__patient', 
        'pv__patient__PatientExtraInfo_patient'
        ).filter(is_e_invoice_registered=False)
        invoices_data_list = []
        for e_inv in inprogress_invoices:
            pv_obj = e_inv.pv
            pt_obj = pv_obj.patient
            #import pdb
            #pdb.set_trace()
            try :extra_pt_obj = pt_obj.PatientExtraInfo_patient
            except :extra_pt_obj =None
            e_inv_obj ={"official_name":extra_pt_obj.official_name if extra_pt_obj else "",
                        "pt_name":pt_obj.fullname,
                               "national_id_14_num":extra_pt_obj.national_id_14_num if extra_pt_obj else "",
                               "passport_code":extra_pt_obj.passport_code if extra_pt_obj else "",
                               "pt_nationality":pt_obj.location.nationality.name,
                               "inv_id":e_inv.id,
                                "pv_id":pv_obj.id,
                               "pt_id":pt_obj.id,
                               "pt_location":pt_obj.location.name,
                               "pt_city":extra_pt_obj.city.name if extra_pt_obj else "",
                               "pt_detail_address":extra_pt_obj.detail_address if extra_pt_obj else "",
                               "pv_ms_name":pv_obj.medicalservice.name,
                               "pv_ms_price":pv_obj.amount_required,
                               "pv_amount_paid":pv_obj.amount_paid,
                               "pv_invoice_serial":pv_obj.invoice_serial,
                               "pv_invoice_notes":pv_obj.invoice_notes,
                    }
            invoices_data_list.append(e_inv_obj)
        #patient_ids = inprogress_invoices.values_list('pv__patient_id',flat=True)
        #inprogress_invoices[0].pv.patient.PatientExtraInfo_patient.city.name 
        #patients_extra_info = PatientExtraInfo.objects.filter(patient_id__in=patient_ids)
        return render(request,"einvoiceApp/e_invoices_in_progress.html",{
            "inprogress_invoices":invoices_data_list,
            'activePage':'EInvoicesInProgress'})
    
    def put(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        data = request.data
        pv_einvoice_id = data["pv_einvoice_id"]
        obj=PvEInvoice.objects.get(id=pv_einvoice_id)
        data._mutable = True
        data.update({"registered_by":request.user.id,"registered_at":timezone.now(),"is_e_invoice_registered":True})
        serializedObj= PvEInvoiceSerializer(obj,data=data,partial=True)
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)#remove from table 
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class EInvoicesDataApi(APIView):
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        return render(request,"einvoiceApp/e_invoices_data.html",{
            'activePage':'EInvoicesData'})
    def post(self,request):
        #if not getClinicId(request) : return redirect('/main/login/')
        data=request.data
        startDate = data["startDate"]
        startDateTime= datetime.strptime(startDate,"%Y-%m-%d")
        endDate = data["endDate"]
        endDateTime= datetime.strptime(endDate,"%Y-%m-%d").replace(hour=23,minute=59,second=59) 
        invoices = PvEInvoice.objects.select_related(
        'pv__patient', 
        'pv__patient__PatientExtraInfo_patient'
        ).filter(registered_at__range=[startDateTime,endDateTime],is_e_invoice_registered=True).order_by("-registered_at")
        invoices_data_list = []
        for e_inv in invoices:
            pv_obj = e_inv.pv
            pt_obj = pv_obj.patient
            try :extra_pt_obj = pt_obj.PatientExtraInfo_patient
            except :extra_pt_obj =None
            #extra_pt_obj = pt_obj.PatientExtraInfo_patient
            e_inv_obj ={
                "pv_id":pv_obj.id,
                "official_name":extra_pt_obj.official_name if extra_pt_obj else "",
                                "pt_name":pt_obj.fullname,
                               #"pt_name":extra_pt_obj.patient.fullname,
                               "pt_id":pt_obj.id,
                               "national_id_14_num":extra_pt_obj.national_id_14_num if extra_pt_obj else "",
                               "passport_code":extra_pt_obj.passport_code if extra_pt_obj else "",
                               "pt_nationality":pt_obj.location.nationality.name,
                               "pt_location":pt_obj.location.name,
                               "pt_city":extra_pt_obj.city.name if extra_pt_obj else "",
                               "pt_detail_address":extra_pt_obj.detail_address if extra_pt_obj else "",
                               "pv_ms_name":pv_obj.medicalservice.name,
                               "pv_ms_price":pv_obj.amount_required,
                               "pv_amount_paid":pv_obj.amount_paid,
                               "pv_invoice_serial":pv_obj.invoice_serial,
                               "pv_invoice_notes":pv_obj.invoice_notes,
                               "registered_by_name":e_inv.registered_by.get_full_name(),
                               "registered_at_date":e_inv.registered_at.strftime("%Y-%m-%d"),
                               "registered_at_time":e_inv.registered_at.strftime("%H:%M"),
                               "registrar_comment":e_inv.registrar_comment,
                    }
            invoices_data_list.append(e_inv_obj)
        return Response(invoices_data_list,status=status.HTTP_200_OK)

            
        #patient_ids = inprogress_invoices.values_list('pv__patient_id',flat=True)
        #inprogress_invoices[0].pv.patient.PatientExtraInfo_patient.city.name 
        #patients_extra_info = PatientExtraInfo.objects.filter(patient_id__in=patient_ids)
        # return render(request,"receptionApp/xxx/ccc/ddd.html",{
        #     "inprogress_invoices":inprogress_invoices,
        #     'activePage':'EInvoicesInProgress'})




class PsInvoiceDataApi(APIView):
    #@method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_patients'), login_url='/main/login/'))
    def get(self,request,ps_id):
        if not getClinicId(request) : return redirect('/main/login/')
        p_visits = PtSurgery.objects.filter(id=ps_id)
        nationalities =Nationality.objects.all()
        locations =Location.objects.all()
        cities =City.objects.all()
        number_type_choices = NUMBER_TYPE_TO_DELIVER_CHOICES
        context = {}
        if p_visits:
            p_visit = p_visits[0]
            patient =p_visit.patient
            patients_extra = PatientExtraInfo.objects.filter(patient=patient)
            patient_extra_obj = patients_extra[0] if patients_extra else None
            context.update({"p_visit":p_visit,"patient":patient,"patient_extra":patient_extra_obj})
        else :
            context.update({"p_visit":None,"patient":None,"patient_extra":None})
        context.update({"nationalities":nationalities,"locations":locations,"cities":cities,"number_type_choices":number_type_choices})
        return render(request,"receptionApp/patientPages/ps_invoice.html",context)
    
    def put(self,request,ps_id):
        obj=PtSurgery.objects.get(id=ps_id)
        data = request.data
        data._mutable = True
        user_id = request.user.id
        data.update({"invoice_last_update_by":user_id,"is_e_invoice_request":True})
        serializedObj= PtSurgeryForInvSerializer(obj,data=data,partial=True)
        if serializedObj.is_valid():
            serializedObj.save()
            #import pdb
            #pdb.set_trace()
            pve_invoice, created = PvEInvoice.objects.get_or_create(pv=obj)
            #pve_invoice.invoice_serial = data["invoice_serial"]
            # pve_invoice.is_e_invoice_registered =True
            # pve_invoice.registrar_comment =data["invoice_notes"] if data["invoice_notes"] else None
            # pve_invoice.registered_by_id =user_id
            # pve_invoice.registered_at =timezone.now()
            # pve_invoice.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class EInvoicesInProgressApi(APIView):
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        #'pv__patient',  # Join PatientVisit to Patient
        #'pv__patient__PatientExtraInfo_patient'  # Join Patient to PatientExtraInfo
        inprogress_invoices = PvEInvoice.objects.select_related(
        'pv__patient', 
        'pv__patient__PatientExtraInfo_patient'
        ).filter(is_e_invoice_registered=False)
        #patient_ids = inprogress_invoices.values_list('pv__patient_id',flat=True)
        #inprogress_invoices[0].pv.patient.PatientExtraInfo_patient.city.name 
        #patients_extra_info = PatientExtraInfo.objects.filter(patient_id__in=patient_ids)
        return render(request,"receptionApp/xxx/ccc/ddd.html",{
            "inprogress_invoices":inprogress_invoices,
            'activePage':'EInvoicesInProgress'})
    def put(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        data = request.data
        pv_einvoice_id = data["pv_einvoice_id"]
        obj=PvEInvoice.objects.get(id=pv_einvoice_id)
        data._mutable = True
        data.update({"registered_by":request.user.id,"registered_at":timezone.now(),"is_e_invoice_registered":True})
        serializedObj= PvEInvoiceSerializer(obj,data=data,partial=True)
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)#remove from table 
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class EInvoicesInProgressApi(APIView):
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        #'pv__patient',  # Join PatientVisit to Patient
        #'pv__patient__PatientExtraInfo_patient'  # Join Patient to PatientExtraInfo
        inprogress_invoices = PvEInvoice.objects.select_related(
        'pv__patient', 
        'pv__patient__PatientExtraInfo_patient'
        ).filter(is_e_invoice_registered=False)
        invoices_data_list = []
        for e_inv in inprogress_invoices:
            pv_obj = e_inv.pv
            pt_obj = pv_obj.patient
            #import pdb
            #pdb.set_trace()
            try :extra_pt_obj = pt_obj.PatientExtraInfo_patient
            except :extra_pt_obj =None
            e_inv_obj ={"official_name":extra_pt_obj.official_name if extra_pt_obj else "",
                        "pt_name":pt_obj.fullname,
                               "national_id_14_num":extra_pt_obj.national_id_14_num if extra_pt_obj else "",
                               "passport_code":extra_pt_obj.passport_code if extra_pt_obj else "",
                               "pt_nationality":pt_obj.location.nationality.name,
                               "inv_id":e_inv.id,
                                "pv_id":pv_obj.id,
                               "pt_id":pt_obj.id,
                               "pt_location":pt_obj.location.name,
                               "pt_city":extra_pt_obj.city.name if extra_pt_obj else "",
                               "pt_detail_address":extra_pt_obj.detail_address if extra_pt_obj else "",
                               "pv_ms_name":pv_obj.medicalservice.name,
                               "pv_ms_price":pv_obj.amount_required,
                               "pv_amount_paid":pv_obj.amount_paid,
                               "pv_invoice_serial":pv_obj.invoice_serial,
                               "pv_invoice_notes":pv_obj.invoice_notes,
                    }
            invoices_data_list.append(e_inv_obj)
        #patient_ids = inprogress_invoices.values_list('pv__patient_id',flat=True)
        #inprogress_invoices[0].pv.patient.PatientExtraInfo_patient.city.name 
        #patients_extra_info = PatientExtraInfo.objects.filter(patient_id__in=patient_ids)
        return render(request,"einvoiceApp/e_invoices_in_progress.html",{
            "inprogress_invoices":invoices_data_list,
            'activePage':'EInvoicesInProgress'})
    
    def put(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        data = request.data
        pv_einvoice_id = data["pv_einvoice_id"]
        obj=PvEInvoice.objects.get(id=pv_einvoice_id)
        data._mutable = True
        data.update({"registered_by":request.user.id,"registered_at":timezone.now(),"is_e_invoice_registered":True})
        serializedObj= PvEInvoiceSerializer(obj,data=data,partial=True)
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)#remove from table 
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class EInvoicesDataApi(APIView):
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        return render(request,"einvoiceApp/e_invoices_data.html",{
            'activePage':'EInvoicesData'})
    def post(self,request):
        #if not getClinicId(request) : return redirect('/main/login/')
        data=request.data
        startDate = data["startDate"]
        startDateTime= datetime.strptime(startDate,"%Y-%m-%d")
        endDate = data["endDate"]
        endDateTime= datetime.strptime(endDate,"%Y-%m-%d").replace(hour=23,minute=59,second=59) 
        invoices = PvEInvoice.objects.select_related(
        'pv__patient', 
        'pv__patient__PatientExtraInfo_patient'
        ).filter(registered_at__range=[startDateTime,endDateTime],is_e_invoice_registered=True).order_by("-registered_at")
        invoices_data_list = []
        for e_inv in invoices:
            pv_obj = e_inv.pv
            pt_obj = pv_obj.patient
            try :extra_pt_obj = pt_obj.PatientExtraInfo_patient
            except :extra_pt_obj =None
            #extra_pt_obj = pt_obj.PatientExtraInfo_patient
            e_inv_obj ={
                "pv_id":pv_obj.id,
                "official_name":extra_pt_obj.official_name if extra_pt_obj else "",
                                "pt_name":pt_obj.fullname,
                               #"pt_name":extra_pt_obj.patient.fullname,
                               "pt_id":pt_obj.id,
                               "national_id_14_num":extra_pt_obj.national_id_14_num if extra_pt_obj else "",
                               "passport_code":extra_pt_obj.passport_code if extra_pt_obj else "",
                               "pt_nationality":pt_obj.location.nationality.name,
                               "pt_location":pt_obj.location.name,
                               "pt_city":extra_pt_obj.city.name if extra_pt_obj else "",
                               "pt_detail_address":extra_pt_obj.detail_address if extra_pt_obj else "",
                               "pv_ms_name":pv_obj.medicalservice.name,
                               "pv_ms_price":pv_obj.amount_required,
                               "pv_amount_paid":pv_obj.amount_paid,
                               "pv_invoice_serial":pv_obj.invoice_serial,
                               "pv_invoice_notes":pv_obj.invoice_notes,
                               "registered_by_name":e_inv.registered_by.get_full_name(),
                               "registered_at_date":e_inv.registered_at.strftime("%Y-%m-%d"),
                               "registered_at_time":e_inv.registered_at.strftime("%H:%M"),
                               "registrar_comment":e_inv.registrar_comment,
                    }
            invoices_data_list.append(e_inv_obj)
        return Response(invoices_data_list,status=status.HTTP_200_OK)
