from rest_framework import serializers

from api.mixins.base_currency import BaseCurrencySerializerMixin
from api.models.data.currency import currency_details as _currency_details_fn
from api.models.data.payroll import Payroll
from api.serializers.data.base import DataRootSerializer


class PayrollSerializer(BaseCurrencySerializerMixin, DataRootSerializer):
    base_currency_amount_fields = (
        'amount', 'basic_salary', 'bonus', 'overtime', 'deductions', 'net_salary',
    )
    base_currency_date_field = 'payment_date'

    currency = serializers.IntegerField()
    # Temporary write aliases for older clients still sending typos
    bunus = serializers.DecimalField(
        max_digits=12, decimal_places=2, required=False, write_only=True
    )
    curency = serializers.IntegerField(required=False, write_only=True)

    employee_details = serializers.SerializerMethodField()
    currency_details = serializers.SerializerMethodField()

    class Meta:
        model = Payroll
        fields = '__all__'
        read_only_fields = (
            'exchange_rate',
            'amount_base',
            'basic_salary_base',
            'bonus_base',
            'overtime_base',
            'deductions_base',
            'net_salary_base',
            'deductions',
        )

    def validate(self, attrs):
        if 'bunus' in attrs and 'bonus' not in attrs:
            attrs['bonus'] = attrs.pop('bunus')
        elif 'bunus' in attrs:
            attrs.pop('bunus')
        if 'curency' in attrs and 'currency' not in attrs:
            attrs['currency'] = attrs.pop('curency')
        elif 'curency' in attrs:
            attrs.pop('curency')

        # API clients that post an explicit payable amount keep it
        initial = getattr(self, 'initial_data', {}) or {}
        if 'amount' in initial or 'net_salary' in initial:
            attrs.setdefault('manual_net', True)

        return super().validate(attrs)

    def get_employee_details(self, obj):
        if obj.employee:
            return {
                'id': obj.employee.id,
                'fullname': obj.employee.full_name,
                'salary': obj.employee.salary,
                'phone': obj.employee.phone,
                'tazkira_number': obj.employee.tazkira_number,
            }
        return None

    def get_currency_details(self, obj):
        return _currency_details_fn(obj.currency)
