from rest_framework import serializers
from .models import Product, Customer, Sale, CreditPayment, Expense


class ProductSerializer(serializers.ModelSerializer):
    total_qty = serializers.ReadOnlyField()

    class Meta:
        model  = Product
        fields = ['id', 'brand', 'weight', 'price', 'full_qty', 'empty_qty', 'total_qty', 'created_at', 'updated_at']


class CustomerSerializer(serializers.ModelSerializer):
    outstanding_credit = serializers.ReadOnlyField()

    class Meta:
        model  = Customer
        fields = ['id', 'name', 'location', 'contact', 'outstanding_credit', 'created_at']


class CreditPaymentSerializer(serializers.ModelSerializer):
    class Meta:
        model  = CreditPayment
        fields = ['id', 'sale', 'amount', 'date', 'note']
        read_only_fields = ['id']


class SaleSerializer(serializers.ModelSerializer):
    customer_name = serializers.SerializerMethodField()
    product_label = serializers.SerializerMethodField()
    credit_payments = CreditPaymentSerializer(many=True, read_only=True)

    class Meta:
        model  = Sale
        fields = [
            'id', 'customer', 'customer_name', 'product', 'product_label',
            'qty', 'amount', 'paid', 'credit',
            'payment_method', 'transaction_number',
            'date', 'created_at', 'credit_payments',
        ]
        read_only_fields = ['id', 'credit', 'created_at']

    def get_customer_name(self, obj):
        return obj.customer.name if obj.customer else 'Walk-in'

    def get_product_label(self, obj):
        return str(obj.product)

    def validate(self, data):
        product = data.get('product') or (self.instance.product if self.instance else None)
        qty     = data.get('qty', 1)
        paid    = data.get('paid', 0)
        amount  = data.get('amount', 0)

        # Check stock availability on create
        if not self.instance and product and product.full_qty < qty:
            raise serializers.ValidationError(
                f"Only {product.full_qty} full cylinders available for {product}."
            )

        # M-Pesa requires a transaction number
        if data.get('payment_method') == 'mpesa' and not data.get('transaction_number', '').strip():
            raise serializers.ValidationError("M-Pesa transaction number is required.")

        if float(paid) < 0 or float(amount) < 0:
            raise serializers.ValidationError("Amount and paid must be non-negative.")

        return data


class ExpenseSerializer(serializers.ModelSerializer):
    class Meta:
        model  = Expense
        fields = ['id', 'category', 'description', 'amount', 'payment_method', 'transaction_number', 'date', 'created_at']
        read_only_fields = ['id', 'created_at']

    def validate(self, data):
        if data.get('payment_method') == 'mpesa' and not data.get('transaction_number', '').strip():
            raise serializers.ValidationError("M-Pesa transaction number is required.")
        return data


# ── Dashboard summary ────────────────────────────────────────────────────────

class DashboardSerializer(serializers.Serializer):
    total_full       = serializers.IntegerField()
    total_empty      = serializers.IntegerField()
    total_revenue    = serializers.DecimalField(max_digits=14, decimal_places=2)
    outstanding_credit = serializers.DecimalField(max_digits=14, decimal_places=2)
    total_expenses   = serializers.DecimalField(max_digits=14, decimal_places=2)
    net_profit       = serializers.DecimalField(max_digits=14, decimal_places=2)
    product_count    = serializers.IntegerField()
    customer_count   = serializers.IntegerField()
    sale_count       = serializers.IntegerField()
    expense_breakdown = serializers.ListField(child=serializers.DictField())