from decimal import Decimal
from rest_framework import serializers
from apps.employee_store.models import (
    EmployeeProfile,
    InternalCategory,
    InternalSubCategory,
    InternalProduct,
    InternalOrder,
    InternalOrderItem,
    DebtPayment,
)
from apps.employee_store.services import has_overdue_weekly_debt


class InternalSubCategorySerializer(serializers.ModelSerializer):
    category_name = serializers.ReadOnlyField(source='category.name')

    class Meta:
        model = InternalSubCategory
        fields = ('id', 'category', 'category_name', 'name', 'description', 'image', 'created_at')


class InternalCategorySerializer(serializers.ModelSerializer):
    subcategories = InternalSubCategorySerializer(many=True, read_only=True)

    class Meta:
        model = InternalCategory
        fields = ('id', 'name', 'description', 'image', 'subcategories', 'created_at')


class InternalProductSerializer(serializers.ModelSerializer):
    category_name = serializers.ReadOnlyField(source='category.name')
    subcategory_name = serializers.ReadOnlyField(source='subcategory.name')

    class Meta:
        model = InternalProduct
        fields = (
            'id',
            'category',
            'category_name',
            'subcategory',
            'subcategory_name',
            'barcode',
            'name',
            'description',
            'price',
            'stock',
            'weekly_limit_per_employee',
            'image',
            'is_active',
            'created_at',
        )


class EmployeeProfileSerializer(serializers.ModelSerializer):
    username = serializers.ReadOnlyField(source='user.username')
    full_name = serializers.SerializerMethodField()
    email = serializers.ReadOnlyField(source='user.email')
    current_debt = serializers.DecimalField(max_digits=12, decimal_places=2, read_only=True)
    has_overdue_debt = serializers.SerializerMethodField()
    overdue_debt_amount = serializers.SerializerMethodField()

    class Meta:
        model = EmployeeProfile
        fields = (
            'id',
            'user',
            'username',
            'full_name',
            'email',
            'employee_number',
            'department',
            'position',
            'salary',
            'is_active',
            'current_debt',
            'has_overdue_debt',
            'overdue_debt_amount',
            'created_at',
        )

    def get_full_name(self, obj):
        return obj.user.get_full_name() or obj.user.username

    def get_has_overdue_debt(self, obj):
        has_debt, _, _ = has_overdue_weekly_debt(obj)
        return has_debt

    def get_overdue_debt_amount(self, obj):
        _, debt_amount, _ = has_overdue_weekly_debt(obj)
        return debt_amount


class InternalOrderItemSerializer(serializers.ModelSerializer):
    product_name = serializers.ReadOnlyField(source='product.name')
    product_barcode = serializers.ReadOnlyField(source='product.barcode')

    class Meta:
        model = InternalOrderItem
        fields = (
            'id',
            'product',
            'product_name',
            'product_barcode',
            'quantity',
            'unit_price',
            'subtotal',
        )


class InternalOrderDetailSerializer(serializers.ModelSerializer):
    employee_number = serializers.ReadOnlyField(source='employee.employee_number')
    employee_name = serializers.SerializerMethodField()
    created_by_name = serializers.SerializerMethodField()
    items = InternalOrderItemSerializer(many=True, read_only=True)

    class Meta:
        model = InternalOrder
        fields = (
            'id',
            'order_number',
            'employee',
            'employee_number',
            'employee_name',
            'total_amount',
            'status',
            'created_by',
            'created_by_name',
            'notes',
            'items',
            'created_at',
        )

    def get_employee_name(self, obj):
        return obj.employee.user.get_full_name() or obj.employee.user.username

    def get_created_by_name(self, obj):
        if obj.created_by:
            return obj.created_by.get_full_name() or obj.created_by.username
        return 'Sistema'


class InternalOrderItemInputSerializer(serializers.Serializer):
    barcode = serializers.CharField(required=False, allow_blank=True, default='')
    product_id = serializers.IntegerField(required=False)
    quantity = serializers.IntegerField(min_value=1, default=1)

    def validate(self, attrs):
        if not attrs.get('barcode') and not attrs.get('product_id'):
            raise serializers.ValidationError("Debe indicar el 'barcode' o el 'product_id'.")
        return attrs


class InternalOrderCreateSerializer(serializers.Serializer):
    employee_id = serializers.IntegerField()
    items = InternalOrderItemInputSerializer(many=True)
    notes = serializers.CharField(required=False, allow_blank=True, default='')
    is_admin_override = serializers.BooleanField(required=False, default=False)

    def validate_items(self, value):
        if not value:
            raise serializers.ValidationError("La orden debe tener al menos un producto.")
        return value


class DebtPaymentSerializer(serializers.ModelSerializer):
    employee_number = serializers.ReadOnlyField(source='employee.employee_number')
    employee_name = serializers.SerializerMethodField()
    registered_by_name = serializers.SerializerMethodField()

    class Meta:
        model = DebtPayment
        fields = (
            'id',
            'employee',
            'employee_number',
            'employee_name',
            'amount',
            'payment_type',
            'registered_by',
            'registered_by_name',
            'reference',
            'notes',
            'created_at',
        )
        read_only_fields = ('registered_by',)

    def get_employee_name(self, obj):
        return obj.employee.user.get_full_name() or obj.employee.user.username

    def get_registered_by_name(self, obj):
        if obj.registered_by:
            return obj.registered_by.get_full_name() or obj.registered_by.username
        return ''
