from rest_framework import serializers
from .models import TransactionReceipt, ReceiptConfig

# ------------------------------
# Transaction Receipt Serializers
# ------------------------------

class TransactionReceiptSerializer(serializers.ModelSerializer):
    generated_by_name = serializers.CharField(source='generated_by.username', read_only=True)

    class Meta:
        model = TransactionReceipt
        fields = [
            'id',
            'receipt_number',
            'transaction_type',
            'member_number',
            'reference_number',
            'created_at',
            'generated_by_name',
            'amount',
            'customer_name',
            'branch_name',
            'transaction_date',
            'status',
            'receipt_data',
            'pdf_file',
        ]
        read_only_fields = ['receipt_number', 'created_at']


class TransactionReceiptCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = TransactionReceipt
        fields = [
            'transaction_type',
            'member_number',
            'reference_number',
            'amount',
            'customer_name',
            'branch_name',
            'transaction_date',
            'status',
            'receipt_data',
        ]

    def create(self, validated_data):
        # Safely get the request and set generated_by
        request = self.context.get('request', None)
        if request and hasattr(request, 'user'):
            validated_data['generated_by'] = request.user
        return super().create(validated_data)

    def validate_transaction_type(self, value):
        """Ensure transaction_type is valid/mapped"""
        valid_types = ['deposit', 'withdrawal', 'share']  # matches model choices
        if value not in valid_types:
            raise serializers.ValidationError("Invalid transaction type.")
        return value

    def validate_status(self, value):
        """Optional: ensure status is valid"""
        valid_statuses = ['active', 'cancelled', 'void']
        if value not in valid_statuses:
            raise serializers.ValidationError(
                f'"{value}" is not a valid status. Must be one of {valid_statuses}.'
            )
        return value



class ReceiptConfigSerializer(serializers.ModelSerializer):
    class Meta:
        model = ReceiptConfig
        fields = [
            'id', 'receipt_type', 'prefix', 'start_number', 'current_number',
            'increment_by', 'format', 'include_date', 'include_time',
            'include_branch_code', 'include_org_code', 'is_active',
            'created_at', 'updated_at'
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']

    def validate(self, data):
        """
        Serializer-level validation to provide user-friendly API errors.
        Model-level clean() still runs on save.
        """
        format_str = data.get('format', '')
        if '{prefix}' not in format_str or '{number}' not in format_str:
            raise serializers.ValidationError({
                'format': 'Format must contain {prefix} and {number} placeholders'
            })

        start_number = data.get('start_number', 0)
        current_number = data.get('current_number', 0)
        if current_number < start_number:
            raise serializers.ValidationError({
                'current_number': 'Current number must be >= start number'
            })

        return data

    def validate_receipt_type(self, value):
        """Ensure receipt_type is unique"""
        qs = ReceiptConfig.objects.filter(receipt_type=value)
        if self.instance:
            qs = qs.exclude(id=self.instance.id)
        if qs.exists():
            raise serializers.ValidationError("Receipt type already exists")
        return value
