from django.shortcuts import render
from django.contrib import auth,messages
from django.shortcuts import render,redirect
from django.contrib.auth.decorators import login_required,user_passes_test
from django.utils.decorators import method_decorator
from mainApp.serializers import *
from mainApp.models import *
from rest_framework.response import Response
from django.contrib.auth.models import  Group, Permission
from rest_framework import status
from django.http import JsonResponse,HttpResponse
from rest_framework.views import APIView
#import json , requests
from django.conf import settings as stg
from datetime import datetime,date,timedelta
from django.db.models import Count,Sum
import json
from django.utils import timezone
# Create your views here.
from surgeryApp.models import *
#from financeApp.models import PtSurgery
from .serializers import *
from mainApp.views import getClinicId

class SurgeriesApi(APIView):
    ##@method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_medicalService'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        all_surgerys =Surgery.objects.all().order_by("is_service")
        all_surgerys_serialized=SurgerySerializer(all_surgerys,many=True)
        return render(request,"surgeryApp/Managment/surgeries.html",{"all_surgerys":all_surgerys_serialized.data,'activePage':'Surgerys'})
    
    ##@method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_medicalService'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        serializedObj= SurgerySerializer(data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class SurgeryApi(APIView):
    def get_object(self,pk):
        try:
            return Surgery.objects.get(pk=pk)
        except Surgery.DoesNotExist:
            return None    
    
    ##@method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_medicalService'), login_url='/main/login/'))        
    def get(self,request,pk): 
        surgeryObj=self.get_object(pk)
        if surgeryObj :
            serializeobj= SurgerySerializer(surgeryObj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    ##@method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_medicalService'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= SurgerySerializer(obj,data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

    ##@method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_medicalService'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

class DoctorsSurgeriesApi(APIView):
    def get_object(self,pk):
        try:
            return User.objects.get(pk=pk)
        except User.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_Organization'), login_url='/main/login/'))        
    def get(self,request,dr_id):
        if not getClinicId(request) : return redirect('/main/login/')
        doctorObj=self.get_object(dr_id)
        if doctorObj :
            mdclSrvcDocObjs =  SurgeryDoctor.objects.filter(doctor=doctorObj)
            msd_serializer= SurgeryDoctorSerializer(mdclSrvcDocObjs,many=True)
            return Response(msd_serializer.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_Organization'), login_url='/main/login/'))    
    def post(self,request,dr_id):
        if not getClinicId(request) : return redirect('/main/login/')
        try:
            request.data._mutable = True
            newPricesJson = request.data.get("newPrices")
            newPricesLst = json.loads(newPricesJson)
            surgeryDrObjs =  SurgeryDoctor.objects.filter(doctor_id=dr_id)
            for obj in newPricesLst :
                if surgeryDrObjs.filter(surgery_id=obj["surgery"]).exists():
                    surgeryDrObj = surgeryDrObjs.get(surgery_id=obj["surgery"])
                    surgeryDrObj.doctor_price=obj["doctor_price"]
                    surgeryDrObj.save()
                else :
                    newObj = SurgeryDoctor(surgery_id=obj["surgery"],doctor_id=dr_id,doctor_price=obj["doctor_price"])
                    newObj.save()
            return Response(status=status.HTTP_200_OK)
        except :return Response(status=status.HTTP_400_BAD_REQUEST)


from django.db.models import Q
import operator
from functools import reduce
class SurgeryReportDoctorApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_MedServiceReportDoctor'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        surgerys = Surgery.objects.filter(is_service=True).values("id","name")
        doctors =User.objects.filter(is_doctor=True,is_active=True).values("id","first_name","last_name")
        return render(request,"mainApp/financePages/surgeries/doctor.html",{
            "surgerys":surgerys,
            "doctors":doctors,
            'activePage':'SurgeryReportDoctor'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_MedServiceReportDoctor'), login_url='/main/login/'))    
    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) 
        doctor = data["doctor"]
        surgery=data["surgery"]
        q_list = [Q(created_at__gte = startDateTime), Q(created_at__lte=endDateTime),Q(visit_status="4F")]
        if surgery != "0" :q_list.append(Q(surgery_id=surgery))
        if doctor != "0" :q_list.append(Q(doctor_id=doctor))
        surgerys = PtSurgery.objects.filter(reduce(operator.and_, q_list)).order_by("-created_at")
        # if surgery != "0" :
        #     surgerys = PtSurgery.objects.filter(created_at__gte = startDateTime , created_at__lte=endDateTime,doctor_id=doctor,visit_status="4F").order_by("created_at")
        # else : 
        #     surgerys = PtSurgery.objects.filter(created_at__gte = startDateTime , created_at__lte=endDateTime,doctor_id=doctor,surgery_id=surgery,visit_status="4F").order_by("created_at")
        serializer= PtSurgeryDoctorSerializer(surgerys,many=True)
        return Response(serializer.data,status=status.HTTP_200_OK)

class CenterSurgeriesApi(APIView):
    #@method_decorator(user_passes_test(lambda u: u.has_perm('Management.view_center_surgeries'), login_url='/main/login/'))
    def get(self,request):
        #if not getClinicId(request) : return redirect('/main/login/')
        timezone_now_today = timezone.now().date()
        #hour_slots_count = HourSlot.objects.count()
        doctors = User.objects.filter(is_active=True,is_doctor=True).values('id',"dr_name_code")
        #visits = PatientVisit.objects.filter(visit_day__gte=timezone_now_today).values("visit_day",).annotate(Count('visit_day',distinct=True),visits=Count('id'))
        surgeries = PtSurgery.objects.filter(surgery_rez_day__gte=timezone_now_today,surgery_type=1).values("surgery_rez_day").annotate(Count('surgery_rez_day',distinct=True),surgeries=Count('id'))
        events =[]
        for day_data in surgeries :
            for dR in doctors :
                dR_surgeries = surgeries.filter(surgery_rez_day=day_data["surgery_rez_day"],doctor_id=dR['id'],)
                if dR_surgeries :
                    #color = '#f56954' if dR_visits[0]["visits"] == hour_slots_count else '#00a65a'#green (#00a65a)
                    color = '#00a65a'#green (#00a65a)
                    events.append(
                    {
                    "title"         : "[{}] {}".format(dR["dr_name_code"],dR_surgeries[0]["surgeries"]),
                    "start"          : day_data["surgery_rez_day"].strftime("%Y-%m-%d"),
                    "allDay"         : "true",
                    "backgroundColor": color, #Success (green)
                    "borderColor"    : color, #Success (green)
                    })
        return render(request,"surgeryApp/Managment/center_surgeries.html",{"events":events,'activePage':'CenterSurgeries'})
'''
SURGERY_TYPES_CHOICES=(
    (1, "C"),#Center , 7ala tb3 el mrkz
    (2, "D"),#Doctor , 7ala tb3 el doctor nfso
)
'''
class AdvanceCSurgeriesApi(APIView):
    ##@method_decorator(user_passes_test(lambda u: u.has_perm('Management.view_patients'), login_url='/main/login/'))
    def get(self,request,surgery_rez_day):
        #if not getClinicId(request) : return redirect('/main/login/')
        ## get all doctors , hrsm el doctor m3 hour slot ,, w hrsm brdo drop down el doctor mnha 
        all_patients =Patient.objects.all().values('id','fullname','code','number_1','number_2','last_visit')
        doctors =User.objects.filter(is_doctor=True,is_active=True).values("id","first_name","last_name")
        surgeries =Surgery.objects.all().values('id', 'name','price')
        #patient_surgeries_ids = patient_surgeries.values_list("id",flat=True)
        #patient , doctor , slot_id 
        #patient_visits_slots = PatientVisitSlot.objects.filter(pv_id__in =patient_visits_ids ).values('hour_slot_id','pv__doctor_id','pv__patient__fullname')
        #all_hour_slots = HourSlot.objects.filter(is_active=True)
        #hour_slots_reserved = {}
        # for d in doctors:
        #     doctor_slots_reserved = patient_visits_slots.filter(pv__doctor_id=d["id"]).values_list("hour_slot",flat=True)
        #     #hour_slots_reserved.append({rT : hour_slot_reserved})
        #     hour_slots_reserved.update({d["id"] : doctor_slots_reserved})
        #     #"patient_name":patient_visits_slots.filter(pv__doctor_id=d["id"],hour_slot_id=)})

        # session_period = request.user.groups.first().clinic.session_period
        return render(request,"surgeryApp/Managment/advance_c_surgeries_day.html",{
            #مش هنعمل اضافة مريض دلوقتى عشان هو المفروض يكشف الاول عند الدكتور عشان كده بياناته موجوده 
            "all_patients":all_patients,
            "doctors":doctors,
            "surgeries":surgeries,
            #"found_ways":FoundWay.objects.all(),
            #"nationalities":Nationality.objects.all(),
            #"locations":Location.objects.all(),
            "surgery_rez_day":surgery_rez_day,
            "surgery_status":SurgeryStatus.objects.all(),
            #"patient_visits_all_clinic_doctors":patient_visits_data,
            #"hour_slots_reserved":hour_slots_reserved,
            #"all_hour_slots":all_hour_slots,
            'activePage':'CenterSurgeries'})
'''
SURGERY_TYPES_CHOICES=(
    (1, "C"),#Center , 7ala tb3 el mrkz
    (2, "D"),#Doctor , 7ala tb3 el doctor nfso
)
'''
class AdvanceDSurgeriesApi(APIView):
    ##@method_decorator(user_passes_test(lambda u: u.has_perm('Management.view_patients'), login_url='/main/login/'))
    def get(self,request,surgery_rez_day):
        #if not getClinicId(request) : return redirect('/main/login/')
        ## get all doctors , hrsm el doctor m3 hour slot ,, w hrsm brdo drop down el doctor mnha 
        all_patients =Patient.objects.all().values('id','fullname','code','number_1','number_2','last_visit')
        doctors =User.objects.filter(is_doctor=True,is_active=True,is_private_surgery=True).values("id","first_name","last_name")
        surgeries =Surgery.objects.all().values('id', 'name','price')
        #patient_surgeries_ids = patient_surgeries.values_list("id",flat=True)
        #patient , doctor , slot_id 
        #patient_visits_slots = PatientVisitSlot.objects.filter(pv_id__in =patient_visits_ids ).values('hour_slot_id','pv__doctor_id','pv__patient__fullname')
        #all_hour_slots = HourSlot.objects.filter(is_active=True)
        #hour_slots_reserved = {}
        # for d in doctors:
        #     doctor_slots_reserved = patient_visits_slots.filter(pv__doctor_id=d["id"]).values_list("hour_slot",flat=True)
        #     #hour_slots_reserved.append({rT : hour_slot_reserved})
        #     hour_slots_reserved.update({d["id"] : doctor_slots_reserved})
        #     #"patient_name":patient_visits_slots.filter(pv__doctor_id=d["id"],hour_slot_id=)})

        # session_period = request.user.groups.first().clinic.session_period
        return render(request,"surgeryApp/Managment/advance_d_surgeries_day.html",{
            #مش هنعمل اضافة مريض دلوقتى عشان هو المفروض يكشف الاول عند الدكتور عشان كده بياناته موجوده 
            "all_patients":all_patients,
            "doctors":doctors,
            "surgeries":surgeries,
            #"found_ways":FoundWay.objects.all(),
            #"nationalities":Nationality.objects.all(),
            #"locations":Location.objects.all(),
            "surgery_rez_day":surgery_rez_day,
            "surgery_status":SurgeryStatus.objects.all(),
            #"patient_visits_all_clinic_doctors":patient_visits_data,
            #"hour_slots_reserved":hour_slots_reserved,
            #"all_hour_slots":all_hour_slots,
            'activePage':'DoctorsSurgeries'})
    
class PtSurgeriesByDayApi(APIView):
    ##@method_decorator(user_passes_test(lambda u: u.has_perm('Management.view_patients'), login_url='/main/login/'))
    def post(self,request,surgery_rez_day,surgery_type):
        if not getClinicId(request) : return redirect('/main/login/')
        ## get all doctors , hrsm el doctor m3 hour slot ,, w hrsm brdo drop down el doctor mnha 
        pt_surgeries = PtSurgery.objects.filter(surgery_rez_day=surgery_rez_day,surgery_type=surgery_type)
        pt_surgeries_serializer = PtSurgeryCustomSerializer(pt_surgeries,many=True)
        return Response(pt_surgeries_serializer.data , status=status.HTTP_200_OK)
    

class PtSurgeriesApi(APIView):
    ##@method_decorator(user_passes_test(lambda u: u.has_perm('Management.add_medicalService'), login_url='/main/login/'))    
    def post(self,request):
        #if not getClinicId(request) : return redirect('/main/login/')
        data=request.data
        data._mutable = True
        data.update({"created_by":request.user.id,"is_confirmed":True if data["is_confirmed"] == "True" else False})
        if "invoice_serial" in data : data["invoice_serial"]=None  if data["invoice_serial"] == "" else data["invoice_serial"]
        serializedObj= PtSurgerySerializer(data=data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(serializedObj.data,status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class PtSurgeryApi(APIView):
    def get_object(self,pk):
        try:
            return PtSurgery.objects.get(pk=pk)
        except PtSurgery.DoesNotExist:
            return None

    ##@method_decorator(user_passes_test(lambda u: u.has_perm('Management.edit_medicalService'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        data = request.data
        data._mutable = True
        if "is_confirmed" in data : 
            data.update({"confirm_by":request.user.id,"confirm_at":timezone.now()})
            data.update({"is_confirmed":True if data["is_confirmed"] == "True" else False })
        if "invoice_serial" in data :data["invoice_serial"]=None  if data["invoice_serial"] == "" else data["invoice_serial"]
        serializedObj= PtSurgerySerializer(obj,data=data,partial=True)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(serializedObj.data,status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

    ##@method_decorator(user_passes_test(lambda u: u.has_perm('Management.delete_medicalService'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)