from rest_framework import serializers

from management.models.flussi import Flusso
from management.models.gruppo_driver import GruppoDriver
from management.models.nota_permanente import NotaPermanente
from management.models.ore_plan import OrePlan
from management.models.plan_archivio import PlanArchivio, PlanArchivioAllegati, TipoDocumento
from management.serializers.cliente_serializer import ClienteSerializer
from management.serializers.fascicolo_serializer import FascicoloSerializer
from management.serializers.gruppo_serializer import GruppoSerializer
from management.serializers.modello_serializer import ModelloSerializer
from management.serializers.pratica_serializer import PraticaSerializer
from management.serializers.stato_pratica_serializer import StatoPraticaSerializer
from management.serializers.utente_serializer import UtenteSerializer
from django.db.models import OuterRef, Subquery 

class TipoDocumentoSerializer(serializers.ModelSerializer):
    class Meta:
        model = TipoDocumento
        fields = '__all__'

class PlanArchivioGetItemsSerializer(serializers.ModelSerializer):
    cliente = ClienteSerializer(many=False, read_only=True)
    pratica = PraticaSerializer(read_only=True)
    # attachments = AbsenceAttachmentListSerializer(many=True, read_only=True)
    modello = ModelloSerializer(many=False, read_only=True)
    gruppo = GruppoSerializer(many=False, read_only=True)
    fascicolo = FascicoloSerializer(many=False, read_only=True)
    stato_pratica = StatoPraticaSerializer(read_only=True)
    documenti = TipoDocumentoSerializer(read_only=True)
    class Meta:
        model = PlanArchivio
        fields = [
            "id",
            "cliente",
            "pratica",
            "pratica_id",
            "modello",
            "gruppo",
            "stato_pratica",
            "stato_pratica_id",
            "fascicolo",
            "title",
            "autorizzazione_fattura",
            "numero_fattura",
            "data_fatturazione",
            "ore_standard",
            "anno_di_lavorazione",
            "mese_di_lavorazione",
            "settimana_di_lavorazione",
            "anno_di_competenza",
            "periodo_di_competenza",
            "data_ora_creazione",
            "data_ora_modifica",
            "data_di_scadenza",
            "incaricato",
            "tariffa",
            "spese",
            "preso_in_carico",
            "documenti",
            "documenti_id",
        ]

class PlanArchivioAllegatiListSerializer(serializers.ModelSerializer):
    """Serializer per la lista degli attachments senza il campo file"""
    class Meta:
        model = PlanArchivioAllegati
        fields = ['id', 'plan', 'nome', 'location', 'data_ora_creazione', 'data_ora_modifica']

class PlanArchivioSerializer(serializers.ModelSerializer):
    attachments = PlanArchivioAllegatiListSerializer(many=True, read_only=True)
    tipo_documento = TipoDocumentoSerializer(read_only=True)

    class Meta:
        model = PlanArchivio
        fields = '__all__' 
    
    def create(self, validated_data):
        plan = PlanArchivio.objects.create(**validated_data)

        pratica_id = plan.pratica_id

        latest_subquery = Flusso.objects.filter(
            pratica_id=OuterRef('pratica_id'),
            random_code=OuterRef('random_code')
        ).order_by('-data_ora_modifica').values('id')[:1]

        flussi_sorgente = Flusso.objects.filter(
            id=Subquery(latest_subquery),
            pratica_id=pratica_id
        ).select_related('group')

        if not flussi_sorgente.exists():
            return plan

        gruppi_ids = set(f.group_id for f in flussi_sorgente if f.group_id)

        gruppi_sorgente = GruppoDriver.objects.filter(id__in=gruppi_ids)

        nuovi_gruppi = []
        for g in gruppi_sorgente:
            nuovi_gruppi.append(GruppoDriver(
                title=g.title,
                plan=plan
            ))

        GruppoDriver.objects.bulk_create(nuovi_gruppi)

        gruppi_creati = list(GruppoDriver.objects.filter(plan=plan))

        mappa_gruppi = {}
        for old, new in zip(gruppi_sorgente, gruppi_creati):
            mappa_gruppi[old.id] = new

        nuovi_flussi = []

        for f in flussi_sorgente:
            nuovi_flussi.append(Flusso(
                title=f.title,
                descrizione=f.descrizione,
                note_attivita=f.note_attivita,
                group=mappa_gruppi.get(f.group_id),
                codice_attivita=f.codice_attivita,
                stato=0,
                pratica=plan.pratica,
                plan=plan,
                random_code=f.random_code
            ))

        Flusso.objects.bulk_create(nuovi_flussi)
        latest_note_subquery = NotaPermanente.objects.filter(
            pratica_id=OuterRef('pratica_id'),
            random_code=OuterRef('random_code')
        ).order_by('-decorrenza', '-id').values('id')[:1]

        note_sorgente = NotaPermanente.objects.filter(
            id=Subquery(latest_note_subquery),
            pratica_id=plan.pratica_id
        )
        nuove_note = []

        for n in note_sorgente:
            nuove_note.append(NotaPermanente(
                descrizione_nota=n.descrizione_nota,
                pratica=plan.pratica,
                plan=plan,
                decorrenza=n.decorrenza,
                random_code=n.random_code
            ))

        if nuove_note:
            NotaPermanente.objects.bulk_create(nuove_note)
        return plan

class OrePlanGetItemsSerializer(serializers.ModelSerializer):
    plan_item = PlanArchivioSerializer(many=False, read_only=True)
    utente = UtenteSerializer(read_only=True)
    autore = UtenteSerializer(read_only=True)

    class Meta:
        model = OrePlan
        fields = '__all__'

class OrePlanSerializer(serializers.ModelSerializer):
   
    class Meta:
        model = OrePlan
        fields = '__all__'

