from django.core.mail import EmailMessage
import os
from django.core.management.base import BaseCommand
from datetime import timedelta
from django.utils import timezone
from management.models import VacationsStates
from management.models.extra_time import ExtraTime
from management.models.extra_time_states import ExtraTimeStates
from management.models.travel_request import TravelRequest
from management.models.user import User
from management.models.vacations import Vacations
from django.template.loader import render_to_string
from django.db.models import Q



class Command(BaseCommand):
    def handle(self, *args, **kwargs):
        # print('check')


##########################################################################################################
#############################################  VACATIONS  ################################################
##########################################################################################################


        vacations_non_approved = Vacations.objects.exclude(Q(state=9) | Q(state=10)| Q(state=19))
        #print('vacations_non_approved ',vacations_non_approved)

        # Estrarre tutti gli ID da vacations_non_approved
        vacations_non_approved_ids = vacations_non_approved.values_list('id', flat=True)

        # Raggruppamento per campo vacation_id
        vacations_states_non_approved_group = (
            VacationsStates.objects
            .filter(vacation_id__in=vacations_non_approved_ids)
        )

        # Convertire in un dizionario, dove la chiave è vacation_id e il valore è una lista di record
        grouped_vacation_states = {}
        for item in vacations_states_non_approved_group:
            vac_id = item.vacation
            if vac_id not in grouped_vacation_states:
                grouped_vacation_states[vac_id] = []
            grouped_vacation_states[vac_id].append(item)

        groups = grouped_vacation_states.items()

        #print('grouped ', grouped_vacation_states)

        #Stampa i dati raggruppati
        # for vac_id, items_in_group in groups:
            # print(f"vacation_id: {vac_id} -> {items_in_group}")

        for vac, items_in_group in groups:
            type_1 = [item for item in items_in_group if item.type == 1 and item.operation is None and vac.emergency != 1]
            type_2 = [item for item in items_in_group if item.type == 2 and item.operation is None and vac.emergency != 1]
            type_3 = [item for item in items_in_group if item.type == 3 and item.operation is None and vac.emergency != 1]
            # print(f"vacation_id: {vac.id} -> type=1 items: {type_1}")
            # print(f"vacation_id: {vac.id} -> type=2 items: {type_2}")
            # print(f"vacation_id: {vac.id} -> type=3 items: {type_3}")
            if type_1:
                self.status_verification(1, items_in_group,vac)
            elif type_2:
                self.status_verification(2, items_in_group,vac)
            elif type_3:
                self.status_verification(3, items_in_group,vac)






#######################################################################################################################
#################################################  EXTRA_TIMES  #######################################################
#######################################################################################################################




        extratime_non_approved = ExtraTime.objects.exclude(Q(state=9) | Q(state=10)| Q(state=19))
        #print('extratime_non_approved ',extratime_non_approved)

        # Estrarre tutti gli ID da vacations_non_approved
        extratime_non_approved_ids = extratime_non_approved.values_list('id', flat=True)

        # Raggruppamento per campo vacation_id
        extratime_states_non_approved_group = (
            ExtraTimeStates.objects
            .filter(extra_time_id__in=extratime_non_approved_ids)
        )

        # Convertire in un dizionario, dove la chiave è vacation_id e il valore è una lista di record
        grouped_extratime_states = {}
        for item in extratime_states_non_approved_group:
            extratime_id = item.extra_time
            if extratime_id not in grouped_extratime_states:
                grouped_extratime_states[extratime_id] = []
            grouped_extratime_states[extratime_id].append(item)

        groups = grouped_extratime_states.items()

        # print('grouped ', grouped_extratime_states)

        #Stampa i dati raggruppati
        # for extratime_id, items_in_group in groups:
        #     print(f"extratime_id: {extratime_id} -> {items_in_group}")

        for extratime, items_in_group in groups:
            type_1 = [item for item in items_in_group if item.type == 1 and item.operation is None]
            type_2 = [item for item in items_in_group if item.type == 2 and item.operation is None]
            type_3 = [item for item in items_in_group if item.type == 3 and item.operation is None] 
            # print(f"extratime_id: {extratime.id} -> type=1 items: {type_1}")
            # print(f"extratime_id: {extratime.id} -> type=2 items: {type_2}")
            # print(f"extratime_id: {extratime.id} -> type=3 items: {type_3}")
            if type_1:
                self.status_verification(1, items_in_group,extratime)
            elif type_2:
                self.status_verification(2, items_in_group,extratime)
            elif type_3:
                self.status_verification(3, items_in_group,extratime)


########################################################################################################################
##################################################  COMMON_FUNCTIONS  ##################################################
########################################################################################################################



    def status_verification(self, type, items_in_group, vac_or_extratime): 
            # print('items,' , items_in_group)
            type_items = [item for item in items_in_group if item.type == type]
            # print(f'type_items {type}:', type_items)

            if type_items:
                operation_null = [item for item in type_items if item.operation == None]

                if operation_null:
                    for item in operation_null:
                        if item.operation == None:
                        # print(item)
                            self.email_responsable_verification(item, vac_or_extratime)
                #se i type_items esistono e sono tutti approvati ( rifiutati non possono essere, perche se un resp ha rifiutato, allora la vacation ha stato 10, che non rientra nel vacations_non_approved
        
           


    def email_responsable_verification(self, item, vac_or_extratime):
        print(f"{vac_or_extratime.id}, {item.type}, {item.approver.id}  {item.approver.surname} email responsable verification secondo")
        now = timezone.now()
        check_time = now.replace(second=0, microsecond=0)
        operation_date = item.operation_date.replace(second=0, microsecond=0)
        threshold_time = check_time - timedelta(minutes=30) 

        #print('operation_date ',operation_date)
        #print('threshold_time ',threshold_time)
        #print('threshold_time -5min ', threshold_time - timedelta(minutes=5))
        #print('vac_or_extratime.type', vac_or_extratime.type)

        if threshold_time - timedelta(minutes=5) <= operation_date < threshold_time:
            if vac_or_extratime.type == 1 or vac_or_extratime.type == 3:
                self.send_second_email(item, vac_or_extratime.type)
            elif vac_or_extratime.type == 2:
                self.send_emergency_admins_email(item, vac_or_extratime) ##now only for Permesso



    def send_second_email(self,instance, type): #instance: state
        name=''
        folder_name = ''
        item=''
        quantity = ''
    

        if type == 1:
            name='Ferie'
            folder_name = 'ferie'
            item = Vacations.objects.get(id=instance.vacation.id)
            quantity = item.quantity
        elif type == 3:
            name='Ore Extra'
            folder_name = 'extra_time'
            item = ExtraTime.objects.get(id=instance.extra_time.id)


        
        date_from_current = item.date_from + timedelta(hours=2)
        date_to_current = item.date_to + timedelta(hours=2)
    

        user = item.user
        approver = User.objects.get(id=instance.approver.id)
        # print(approver.mail)

        context = {
            'user': {'givenName': user.givenName, 'surname': user.surname},
            'id': item.id,
            'date_from': date_from_current,
            'date_to': date_to_current,
            'state': item.state,
            'note': item.note,
            'type': item.type,
            'quantity': quantity,
        }
        
        html_content_responsable = render_to_string(f"email/{folder_name}/promemory.html", context)

        email_responsable = EmailMessage(
        subject=f"Promemoria: nuova richiesta {name}",
        body=html_content_responsable,
        from_email=os.getenv("SMTP_SENDER_EMAIL"),
        to=[approver.mail], #[approver.mail] #production mode
        )

        email_responsable.content_subtype = "html"
        email_responsable.send() #production mode

        print(f'send_second_email to responsable {approver.mail} for states!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')



    def send_emergency_admins_email(self, instance, item):
            
            # print(type)
            name='Permesso'
            folder_name = 'permesso'
            quantity = item.quantity

            print('item.emergency', item.emergency)


            if item.emergency == False:
                
                #Imposto il flag di emergenza
                item.emergency = True
                item.save()

                #Aggiorno lo stato di tutti i vacation_states precedenti senza risposta
                without_response = VacationsStates.objects.filter(
                        vacation_id=instance.vacation.id,
                        operation__isnull=True
                    ).exclude(type=3)
                for obj in without_response:
                    obj.operation = 3
                VacationsStates.objects.bulk_update(without_response, ['operation'])
    

                date_from_current = item.date_from + timedelta(hours=2)
                date_to_current = item.date_to + timedelta(hours=2)
            
                user = item.user


                vac_state_admins = User.objects.filter(
                id__in=VacationsStates.objects.filter(
                vacation_id=instance.vacation.id,
                type=3
                ).values_list('approver', flat=True),
                role=1)


                users_to = User.objects.filter(Q(role=1) | Q(role=2))    


                for user_to in users_to:
                    if user_to and user_to in vac_state_admins:
                        VacationsStates.objects.filter(
                            vacation=instance.vacation,
                            approver=user_to,
                            type=3
                        ).update(operation=None, operation_date=timezone.now())

                    else:
                        new_admin_state = VacationsStates(
                            vacation=item,  
                            approver=user_to,
                            type=3,
                            request_date=timezone.now(),
                            operation=None,
                            operation_date=timezone.now(),
                        )

                        new_admin_state.save()

                    # users_cc = User.objects.filter(Q(role=2))
                    # admins_list_cc_mails = [user.mail for user in users_cc] 
                    # admins_list_cc_mails = list(admins_list_cc_mails)

                    print(f'admin_mail: {user_to}')

                    context = {
                            'user': {'givenName': user.givenName, 'surname': user.surname},
                            'id': item.id,
                            'date_from': date_from_current,
                            'date_to': date_to_current,
                            'state': item.state,
                            'note': item.note,
                            'type': item.type,
                            'quantity': quantity,
                    }
                            
                    html_content_emergency = render_to_string(f"email/{folder_name}/emergency.html", context)

                    email_responsable = EmailMessage(
                        subject=f"EMERGENZA: nuova richiesta di {name}",
                        body=html_content_emergency,
                        from_email=os.getenv("SMTP_SENDER_EMAIL"),
                        to=[user_to.mail], #[admin_mail] #production mode
                    )
                    email_responsable.content_subtype = "html"
                    email_responsable.send() #production mode
                    print(f'emerg email to admin {user_to.mail} for non approved state')

