from django.shortcuts import render

from app.entities import models
from app.applicationlayer import paginators

from datetime import datetime

from rest_framework.response import Response
from rest_framework import status, views

from rest_framework.decorators import action
from django.http import Http404

from django.db.models import Q


def list_by_user(user_id_number):

    return_queryset = None

    try:
    
        approver = models.ChangeRequestFormApprovers.objects.filter(
            Q(user=user_id_number) &
            Q(deleted_at=None)
        )
        approver = [data['form_code'] for data in approver]
        stake = models.ChangeRequestFormStakeHolders.objects.filter(
                    Q(user=user_id_number) &
                    Q(deleted_at=None)
        )
        stake = [data['form_code'] for data in stake]
        headers = models.ChangeRequestFormHeader.objects.filter(
            deleted_at=None,
            requested_by_user=user_id_number
        )
        headers = [data['form_code'] for data in headers]

        # # TODO: Include priviledges here
        # req = get_allowed_company(user_id_number)
        # results = req.json()['results']

        # # Get the list of distincted group_no
        # crViews = list(set(
        #     map(lambda x: x['group_pivots'],
        #         list(filter(lambda x: x['view_all_change_request'], results))
        #     )
        # ))

        # priviledgedList = models.ChangeRequestFormHeader.objects.filter(
        #     requested_to_department__in=crViews,
        #     deleted_at=None,
        # )
        # priviledgedCrs = [data['form_code'] for data in priviledgedList]

        # form_code = list(set(stake + approver + headers + priviledgedCrs))
        
        form_code = list(set(stake + approver + headers))

        return_queryset = models.ChangeRequestFormHeader.objects.filter(
            form_code__in=form_code,
            deleted_at=None,
        )
        exclude = return_queryset.filter(
            status__iexact='Draft',
            requested_by_user__ne=user_id_number
        )
        exclude = [data['form_code'] for data in exclude]

        return_queryset = return_queryset.filter(
                form_code__nin=exclude
        )

    except Exception as e:
        pass
    
    return return_queryset


def filter_base(base_queryset,
                company_requested_to,
                department_requested_to,
                date_modified_from,
                date_modified_to,
                date_required_from,
                date_required_to,
                form_type):

    return_queryset = base_queryset

    try:

        if company_requested_to:
            return_queryset = return_queryset.filter(requested_to_company__exact=company_requested_to)
       
        if department_requested_to:
            return_queryset = return_queryset.filter(requested_to_department__exact=department_requested_to)

        if form_type == 'open':
            return_queryset = return_queryset.filter(status__ne='Closed')

        elif form_type == 'closed':
            return_queryset = return_queryset.filter(status='Closed')

        date_modified = []
        date_modified_not = []
    
        if date_modified_from and date_modified_to:
 
            for query in return_queryset:
                created = datetime.strftime(query.created, "%Y-%m-%d")
                
                if created >= date_modified_from and created <= date_modified_to:
                    date_modified.append(query.id)
                    return_queryset = return_queryset.filter(id__in=date_modified)
                else:          
                    date_modified_not.append(query.id)
                    return_queryset = return_queryset.filter(id__nin=date_modified_not)
    
        date_required = []
        date_required_not = []
    
        if date_required_from and date_required_to:
            for query in return_queryset:
                 
                 try:
                      if query.requested_to_target_date:
                           
                           requested_to_target_date = datetime.strptime(query.requested_to_target_date[:-1], "%Y-%m-%dT%H:%M:%S.%f")
                           requested_to_target_date = datetime.strftime(requested_to_target_date, "%Y-%m-%d")
                           
                           if requested_to_target_date >= date_required_from and requested_to_target_date <= date_required_to:
                                
                                date_required.append(query.id)
                                return_queryset = return_queryset.filter(id__in=date_required)
                           else:
                                date_required_not.append(query.id)
                                return_queryset = return_queryset.filter(id__nin=date_required_not)
                      else:
                           date_required_not.append(query.id)
                           return_queryset = return_queryset.filter(id__nin=date_required_not)
    
                 except ValueError:
                      
                      if query.requested_to_target_date:
                           
                           requested_to_target_date = datetime.strptime(query.requested_to_target_date[:-1], "%Y-%m-%d %H:%M:%S")
                           requested_to_target_date = datetime.strftime(requested_to_target_date, "%Y-%m-%d")
                           
                           if requested_to_target_date >= date_required_from and requested_to_target_date <= date_required_to:
                                
                                date_required.append(query.id)
                                return_queryset = return_queryset.filter(id__in=date_required)
                           else:
                                date_required_not.append(query.id)
                                return_queryset = return_queryset.filter(id__nin=date_required_not)
                      else:
                           date_required_not.append(query.id)
                           return_queryset = return_queryset.filter(id__nin=date_required_not)

        return_queryset

    except Exception as e:
        pass

    return return_queryset


def filter_overdue(base_queryset):

    return_queryset = base_queryset

    try:

        now = datetime.now()
        overdue = []
        
        for query in return_queryset:
            
            try:
                if query.requested_to_target_date:
                    requested_to_target_date = datetime.strptime(query.requested_to_target_date[:-1], "%Y-%m-%dT%H:%M:%S.%f")
                
                    if (requested_to_target_date < now):
                        overdue.append(query.form_code)

            except ValueError:

                #convert now
                if query.requested_to_target_date:
                    requested_to_target_date = datetime.strptime(query.requested_to_target_date[:-1], "%Y-%m-%d %H:%M:%S")
                
                    if (requested_to_target_date < now):
                        overdue.append(query.form_code)

            return_queryset = return_queryset.filter(
                form_code__in=overdue
            )

        return_queryset

    except Exception as e:
        pass

    return return_queryset


def filter_status(base_queryset,
                  status):

    return_queryset = base_queryset

    try:

        if status:

            return_queryset = return_queryset.filter(
                status__iexact=status
            )

        return_queryset

    except Exception as e:
        pass

    return return_queryset


def filter_awaiting(base_queryset,
                    user_id_number):

    return_queryset = base_queryset
    
    try:
        awaiting_included = []
        
        for query in return_queryset:
            
            current_level = models.ChangeRequestFormApprovers.objects.filter(
                Q(form_code=query.form_code) &
                Q(deleted_at=None) &
                (Q(action='') | Q(action=None))
            ).order_by('level')
            
            if current_level:
                
                if current_level[0]['user'] == user_id_number:
                    awaiting_included.append(query.form_code)

        return_queryset = return_queryset.filter(form_code__in=awaiting_included)
    
    except Exception as e:
        pass

    return return_queryset
