from decimal import Decimal
from rest_framework import serializers , fields

from collections import defaultdict
from app_venin_web_new1.services import actualizar_stock_producto, calcular_costo_para_guia
from app_venin_web_new1.utils import numero_a_letras_con_centavos
from .models import *
from django.contrib.auth import get_user_model
from django.db import transaction, models as dj_models


class UserSerializer(serializers.ModelSerializer):
    username = serializers.CharField(required=True)
    password = serializers.CharField(min_length=8, required=True, write_only=True)
    idpersonal = serializers.SerializerMethodField()
    idsucursal = serializers.SerializerMethodField()
    aprobador = serializers.SerializerMethodField()
    
    class Meta:
        model = get_user_model()
        fields = '__all__'
        depth = 1 #('username', 'password')
    
    def get_idsucursal(self, user):
        try:
            personal = Personal.objects.get(idusuario=user)
            return personal.idsucursal.idsucursal  
        except Personal.DoesNotExist:
            return None
        
    def get_idpersonal(self, user):
        try:
            personal = Personal.objects.get(idusuario=user)
            return personal.idpersonal  
        except Personal.DoesNotExist:
            return None
        
    def get_aprobador(self, user):
        try:
            aprobador = Aprobador.objects.get(idusuario=user)
            
            return {
                'idaprobador': aprobador.pk,
                'nombre': aprobador.idusuario.first_name, 
                'cargo': aprobador.cargo,
                'codigo': aprobador.codigo
            }
        except Aprobador.DoesNotExist:
            return None

class SucursalSerializer(serializers.ModelSerializer):
    class Meta:
        model = Sucursal
        fields = '__all__'

class EmpresaWriteSerializer(serializers.ModelSerializer):
    class Meta:
        model = Empresa
        fields = '__all__'
        extra_kwargs = {
            'logo': {'required': False},
            'logo2': {'required': False},
            'logo3': {'required': False}
        }


class EmpresaReadSerializer(serializers.ModelSerializer):
    logo = serializers.SerializerMethodField()
    logo2 = serializers.SerializerMethodField()
    logo3 = serializers.SerializerMethodField()

    class Meta:
        model = Empresa
        fields = '__all__'

    def _get_image_url(self, obj, field_name):
        image = getattr(obj, field_name)
        if image:
            request = self.context.get('request')
            return request.build_absolute_uri(image.url) if request else image.url
        return None

    def get_logo(self, obj):
        return self._get_image_url(obj, 'logo')

    def get_logo2(self, obj):  
        return self._get_image_url(obj, 'logo2')

    def get_logo3(self, obj):  
        return self._get_image_url(obj, 'logo3')
     
class EmpresaSerializer(serializers.ModelSerializer):
    logo = serializers.ImageField(use_url=True, required=False)
    logo2 = serializers.ImageField(use_url=True, required=False)
    logo3 = serializers.ImageField(use_url=True, required=False)

    class Meta:
        model = Empresa
        
        fields = ['razonsocial','direccion','logo','logo2','logo3','ruc','nombrecomercial','banco','cuenta','cci','refran','email','telefono',
                  'fax','email','codigofis','dtr_bconac','codigoubigeo']

class EmpleadoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Empleado
        fields = '__all__'
        
    def to_representation(self, instance):
        response = super().to_representation(instance)
        
        response['departamento'] = {
            'id_departamento': instance.departamento.id_departamento, 
            'nombre': instance.departamento.nombre
        } if instance.departamento else None
        
        response['cargo'] = {
            'id_cargo': instance.cargo.id_cargo, 
            'nombre': instance.cargo.nombre
        } if instance.cargo else None
        
        response['afp'] = {
            'id_afp': instance.afp.id_afp, 
            'nombre': instance.afp.nombre
        } if instance.afp else None
        
        response['banco'] = {
            'id_banco': instance.banco.id_banco, 
            'nombre': instance.banco.nombre
        } if instance.banco else None
        
        return response

class BancoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Banco
        fields = '__all__'

class DepartamentoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Departamento
        fields = '__all__'

class CargoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Cargo
        fields = '__all__'

class TasaGeneralSerializer(serializers.ModelSerializer):
    class Meta:
        model = TasaGeneral
        fields = '__all__'

class RegimenPensionarioSerializer(serializers.ModelSerializer):
    class Meta:
        model = RegimenPensionario
        fields = '__all__'
        
class TasaMensualSerializer(serializers.ModelSerializer):
    afp_nombre = serializers.ReadOnlyField(source='afp.nombre')

    class Meta:
        model = AfpTasasMensuales
        fields = '__all__'
        
class PlanillaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Planilla
        fields = '__all__'
        
class PlanillaDetalleSerializer(serializers.ModelSerializer):
    
    empleado = serializers.PrimaryKeyRelatedField(queryset=Empleado.objects.all())
    cargo = serializers.PrimaryKeyRelatedField(queryset=Cargo.objects.all(), required=False, allow_null=True)
    departamento = serializers.PrimaryKeyRelatedField(queryset=Departamento.objects.all(), required=False, allow_null=True)
    afp = serializers.PrimaryKeyRelatedField(queryset=RegimenPensionario.objects.all(), required=False, allow_null=True)

    class Meta:
        model = PlanillaDetalle
        fields = '__all__'

    def to_representation(self, instance):
        response = super().to_representation(instance)

        response['cargo'] = {
            'id_cargo': instance.cargo.id_cargo,
            'nombre': instance.cargo.nombre
        } if instance.cargo else None

        response['departamento'] = {
            'id_departamento': instance.departamento.id_departamento,
            'nombre': instance.departamento.nombre
        } if instance.departamento else None

        response['afp'] = {
            'id_afp': instance.afp.id_afp,
            'nombre': instance.afp.nombre,
            'tipo': instance.afp.tipo
        } if instance.afp else None

        if instance.empleado:
            response['empleado'] = {
                'id_empleado': instance.empleado.id_empleado,
                'dni': instance.empleado.dni,
                'nombres': instance.empleado.nombres,
                'apellido_paterno': instance.empleado.apellido_paterno,
                'apellido_materno': instance.empleado.apellido_materno,
                'fecha_ingreso': instance.empleado.fecha_ingreso,
                'fecha_cese': instance.empleado.fecha_cese,
                'categoria': instance.empleado.categoria,
                'nro_cuenta': instance.empleado.nro_cuenta
            }
        return response
    
class CuentaContableSerializer(serializers.ModelSerializer):
    nombre_concepto = serializers.CharField(source='concepto.etiqueta', read_only=True)

    class Meta:
        model = CuentaContable
        fields = '__all__'

class ConceptoContableSerializer(serializers.ModelSerializer):
    cuenta = CuentaContableSerializer(source='cuentacontable', read_only=True)

    class Meta:
        model = ConceptoContable
        fields = ['id_concepto', 'campo_interno', 'etiqueta', 'orden', 'activo', 'cuenta']