from decimal import Decimal
from rest_framework import serializers
from shop_management.models.data.customer import Customer
from shop_management.serializers.data.base import DataRootSerializer
from shop_management.serializers.data.shop import ShopSerializer
from shop_management.serializers.data.utils import CurrencySerializer


class CustomerSerializer(DataRootSerializer):
    shop_details = ShopSerializer(source='shop', read_only=True)
    opening_balance_currency_details = serializers.SerializerMethodField()
    remaining_opening_balance_afn = serializers.SerializerMethodField()
    remaining_opening_balance_usd = serializers.SerializerMethodField()
    original_opening_balances_by_currency = serializers.SerializerMethodField()
    paid_opening_balances_by_currency = serializers.SerializerMethodField()
    opening_balances_by_currency = serializers.SerializerMethodField()
    total_owed_by_currency = serializers.SerializerMethodField()
    credit_by_currency = serializers.SerializerMethodField()

    class Meta:
        model = Customer
        fields = '__all__'
        extra_kwargs = {
            "name": {"required": True, "allow_blank": False, "allow_null": False},
        }

    def get_opening_balance_currency_details(self, obj):
        if obj.opening_balance_currency:
            return CurrencySerializer(obj.opening_balance_currency).data
        return None

    def get_remaining_opening_balance_afn(self, obj):
        return float(obj.remaining_opening_balance_afn)

    def get_remaining_opening_balance_usd(self, obj):
        return float(obj.remaining_opening_balance_usd)

    def get_original_opening_balances_by_currency(self, obj):
        return obj.get_original_opening_balances_by_currency()

    def get_paid_opening_balances_by_currency(self, obj):
        return obj.get_paid_opening_balances_by_currency()

    def get_opening_balances_by_currency(self, obj):
        return obj.get_opening_balances_by_currency()

    def get_total_owed_by_currency(self, obj):
        """Opening balance + unpaid sale amounts per currency (what the customer owes)."""
        return obj.get_total_owed_by_currency()

    def get_credit_by_currency(self, obj):
        return obj.get_credit_by_currency()

    def validate_name(self, value):
        value = (value or "").strip()
        if not value:
            raise serializers.ValidationError("Customer name is required.")
        return value

    def validate_opening_balance_afn(self, value):
        val = Decimal(str(value or 0))
        if val < 0:
            raise serializers.ValidationError("Opening balance (AFN) cannot be negative.")
        return val

    def validate_opening_balance_usd(self, value):
        val = Decimal(str(value or 0))
        if val < 0:
            raise serializers.ValidationError("Opening balance (USD) cannot be negative.")
        return val

    def to_representation(self, instance):
        data = super().to_representation(instance)
        base = (instance.name or "").strip()
        if not base and instance.email:
            base = str(instance.email).split("@")[0].strip()
        if not base and instance.contact:
            base = str(instance.contact).strip()
        if not base:
            base = "Unnamed Customer"
        data["name"] = f"General Customer-{base}" if instance.is_general_customer else base
        return data
