from rest_framework import serializers
from .models import *
from ledgers.models import SystemTransactions


# ------------------ Deposits ------------------ #
class USSDDepositInitiationsSerializer(serializers.ModelSerializer):
    customer_name               = serializers.CharField(source='account.account_customer.name', read_only=True)
    customer_member_number      = serializers.CharField(source='account.account_customer.member_number', read_only=True)
    customer_old_member_number  = serializers.CharField(source='account.account_customer.old_member_number', read_only=True)
    account_number              = serializers.CharField(source='account.account_no', read_only=True)
    branch                      = serializers.CharField(source='account.customer_branch.name', read_only=True)

    class Meta:
        model = USSDDepositInitiations
        fields = '__all__'


class USSDDepositTransactionsSerializer(serializers.ModelSerializer):
    """Serializer for deposit transactions from SystemTransactions"""
    status = serializers.SerializerMethodField()
    phone = serializers.SerializerMethodField()
    member_number = serializers.SerializerMethodField()
    transaction_id = serializers.CharField(source='reference_no', read_only=True)
    organisation_id = serializers.IntegerField(source='branch.branch_organisation.id', read_only=True)
    account = serializers.SerializerMethodField()
    customer_name = serializers.SerializerMethodField()
    customer_member_number = serializers.SerializerMethodField()
    customer_old_member_number = serializers.SerializerMethodField()
    account_number = serializers.SerializerMethodField()
    branch_name = serializers.CharField(source='branch.name', read_only=True)
    date_added = serializers.DateTimeField(read_only=True)
    charge = serializers.SerializerMethodField()

    class Meta:
        model = SystemTransactions
        fields = ['id', 'amount', 'charge', 'phone', 'member_number', 'transaction_id', 'organisation_id', 
                  'account', 'status', 'date_added', 'customer_name', 'customer_member_number',
                  'customer_old_member_number', 'account_number', 'branch_name', 'heading', 
                  'reference_no', 'payment_method']

    def get_status(self, obj):
        return 'processed'

    def get_charge(self, obj):
        return 0

    def get_phone(self, obj):
        # Extract phone from heading if it contains phone pattern
        import re
        if obj.heading:
            phone_match = re.search(r'(\d{9,12})', obj.heading)
            if phone_match:
                return phone_match.group(1)
        return ''

    def get_member_number(self, obj):
        # Try to get from related saving account transaction
        try:
            from savings.models import SavingAccountTransactions
            saving_trans = SavingAccountTransactions.objects.filter(transaction=obj).first()
            if saving_trans and saving_trans.customer_account:
                return saving_trans.customer_account.account_customer.member_number
        except:
            pass
        return ''

    def get_account(self, obj):
        try:
            from savings.models import SavingAccountTransactions
            saving_trans = SavingAccountTransactions.objects.filter(transaction=obj).first()
            if saving_trans:
                return saving_trans.customer_account.id
        except:
            pass
        return None

    def get_customer_name(self, obj):
        try:
            from savings.models import SavingAccountTransactions
            saving_trans = SavingAccountTransactions.objects.filter(transaction=obj).first()
            if saving_trans and saving_trans.customer_account:
                return saving_trans.customer_account.account_customer.name
        except:
            pass
        # Try to extract from heading
        if obj.heading and 'by ' in obj.heading:
            parts = obj.heading.split('by ')
            if len(parts) > 1:
                name_part = parts[1].split(' - ')[0].strip()
                return name_part
        return ''

    def get_customer_member_number(self, obj):
        return self.get_member_number(obj)

    def get_customer_old_member_number(self, obj):
        try:
            from savings.models import SavingAccountTransactions
            saving_trans = SavingAccountTransactions.objects.filter(transaction=obj).first()
            if saving_trans and saving_trans.customer_account:
                return saving_trans.customer_account.account_customer.old_member_number or ''
        except:
            pass
        return ''

    def get_account_number(self, obj):
        try:
            from savings.models import SavingAccountTransactions
            saving_trans = SavingAccountTransactions.objects.filter(transaction=obj).first()
            if saving_trans and saving_trans.customer_account:
                return saving_trans.customer_account.account_no
        except:
            pass
        return ''


class USSDDepositLiquidationsSerializer(serializers.ModelSerializer):
    request_added_by = serializers.CharField(read_only=True)
    requester_name   = serializers.CharField(source='request_added_by.user_staff', read_only=True)
    branch           = serializers.PrimaryKeyRelatedField(read_only=True, required=False)
    organisation     = serializers.PrimaryKeyRelatedField(read_only=True, required=False)

    class Meta:
        model = USSDDepositLiquidations
        fields = '__all__'


class USSDLiquidationTransactionsSerializer(serializers.ModelSerializer):
    """Serializer for liquidation transactions from SystemTransactions"""
    requested_amount = serializers.DecimalField(source='amount', max_digits=10, decimal_places=2, read_only=True)
    approved_amount = serializers.DecimalField(source='amount', max_digits=10, decimal_places=2, read_only=True)
    selected_account = serializers.SerializerMethodField()
    selected_account_name = serializers.SerializerMethodField()
    status = serializers.SerializerMethodField()
    organisation = serializers.IntegerField(source='branch.branch_organisation.id', read_only=True)
    transaction_date = serializers.DateTimeField(source='date_added', read_only=True)
    request_added_by = serializers.SerializerMethodField()
    request_added_by_name = serializers.SerializerMethodField()
    approved_by = serializers.SerializerMethodField()
    approved_by_name = serializers.SerializerMethodField()
    comment = serializers.SerializerMethodField()
    branch_name = serializers.CharField(source='branch.name', read_only=True)

    class Meta:
        model = SystemTransactions
        fields = ['id', 'requested_amount', 'approved_amount', 'selected_account', 'selected_account_name',
                  'payment_method', 'status', 'organisation', 'transaction_date', 'request_added_by',
                  'request_added_by_name', 'approved_by', 'approved_by_name', 'comment', 'heading', 
                  'reference_no', 'amount', 'branch_name']

    def get_status(self, obj):
        return 'approved'

    def get_selected_account(self, obj):
        # For liquidations, e-wallet is credited, so the debit_chart is the selected account
        return obj.debit_chart.id if obj.debit_chart else None

    def get_selected_account_name(self, obj):
        return obj.debit_chart.account_name if obj.debit_chart else ''

    def get_request_added_by(self, obj):
        return obj.added_by.id if obj.added_by else None

    def get_request_added_by_name(self, obj):
        if obj.added_by:
            return f"{obj.added_by.first_name} {obj.added_by.last_name}".strip() or obj.added_by.username
        return ''

    def get_approved_by(self, obj):
        return obj.added_by.id if obj.added_by else None

    def get_approved_by_name(self, obj):
        if obj.added_by:
            return f"{obj.added_by.first_name} {obj.added_by.last_name}".strip() or obj.added_by.username
        return ''

    def get_comment(self, obj):
        return obj.coment or ''


# ------------------ Withdrawals ------------------ #
class USSDWithdrawalInitiationsSerializer(serializers.ModelSerializer):
    customer_name               = serializers.CharField(source='account.account_customer.name', read_only=True)
    customer_member_number      = serializers.CharField(source='account.account_customer.member_number', read_only=True)
    customer_old_member_number  = serializers.CharField(source='account.account_customer.old_member_number', read_only=True)
    account_number              = serializers.CharField(source='account.account_no', read_only=True)
    branch                      = serializers.CharField(source='account.customer_branch.name', read_only=True)

    class Meta:
        model = USSDWithdrawalInitiations
        fields = '__all__'


class USSDWithdrawalLiquidationsSerializer(serializers.ModelSerializer):
    request_added_by = serializers.CharField(read_only=True)
    requester_name   = serializers.CharField(source='request_added_by.user_staff', read_only=True)
    branch           = serializers.PrimaryKeyRelatedField(read_only=True, required=False)
    organisation     = serializers.PrimaryKeyRelatedField(read_only=True, required=False)

    class Meta:
        model = USSDWithdrawalLiquidations
        fields = '__all__'


# ------------------ Mobile Money Service Providers ------------------ #
class MMServiceProviderSerializer(serializers.ModelSerializer):
    class Meta:
        model = MMServiceProvider
        fields = '__all__'


class MMServiceProviderTarrifSerializer(serializers.ModelSerializer):
    charge_name     = serializers.CharField(read_only=True)
    tarrif_added_by = serializers.CharField(read_only=True)

    class Meta:
        model = MMServiceProviderTarrif
        fields = '__all__'



# from rest_framework import serializers
# from .models import *


# class USSDDepositInitiationsSerializer(serializers.ModelSerializer):
#     customer_name               = serializers.CharField(source='account.account_customer.name',read_only=True)
#     customer_member_number      = serializers.CharField(source='account.account_customer.member_number',read_only=True)
#     customer_old_member_number  = serializers.CharField(source='account.account_customer.old_member_number',read_only=True)
#     account_number              = serializers.CharField(source='account.account_no', read_only=True)
#     branch                      = serializers.CharField(source='account.customer_branch.name', read_only=True)
#     class Meta:
#         model = USSDDepositInitiations
#         fields = '__all__'

# class USSDDepositLiquidationsSerializer(serializers.ModelSerializer):
#     request_added_by = serializers.CharField(read_only=True)
#     requester_name   = serializers.CharField(source='request_added_by.user_staff',read_only=True)
#     branch           = serializers.PrimaryKeyRelatedField(read_only=True, required=False)
#     organisation     = serializers.PrimaryKeyRelatedField(read_only=True, required=False)


#     class Meta:
#         model = USSDDepositLiquidations
#         fields = '__all__'

# class MMServiceProviderSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = MMServiceProvider
#         fields = '__all__'

# class MMServiceProviderTarrifSerializer(serializers.ModelSerializer):
#     charge_name     = serializers.CharField(read_only=True)
#     tarrif_added_by = serializers.CharField(read_only=True)
#     class Meta:
#         model = MMServiceProviderTarrif
#         fields = '__all__'