import math


def update_breeding_female_status(inner_animal_trait_dict, month_index):
    """Update derived traits of a single animal type that is breeding females.

    Because breeding females undergo cycles of conception, pregnancy, and
    lactation, some derived traits must be updated at each model time step.
    These traits do not vary spatially.

    Parameters:
        inner_animal_trait_dict (dict): dictionary of key, value pairs
            representing input and derived traits for this animal type.
        month_index (int): month of the simulation, such that month_index=13
            indicates month 13 of the simulation

    Returns:
        updated_trait_table, a dictionary of key, value pairs where values
        indicate input and derived traits for this animal type, including the
        following updated animal traits:
            - reproductive_status_int, integer indicating animal reproductive
                status:
                0: not pregnant or lactating (default)
                1: pregnant
                2: lactating
            - W_total, total weight including weight of conceptus if pregnant
            - A_foet, age of the foetus if pregnant
            - A_y, age of the suckling young if lactating

    """
    updated_trait_table = inner_animal_trait_dict.copy()
    months_of_pregnancy = 9
    cycle_month_index = (
        (month_index - updated_trait_table['conception_step']) %
        updated_trait_table['calving_interval'])
    if cycle_month_index < months_of_pregnancy:
        # animal is pregnant
        updated_trait_table['reproductive_status_int'] = 1
        updated_trait_table['A_foet'] = cycle_month_index * 30 + 1
        RA = updated_trait_table['A_foet'] / updated_trait_table['CP1']
        BW = (
            (1 - updated_trait_table['CP4'] +
                updated_trait_table['CP4'] *
                updated_trait_table['Z']) *
            updated_trait_table['CP15'] *
            updated_trait_table['SRW_modified'])
        W_c_1 = updated_trait_table['CP5'] * BW
        W_c_2 = math.exp(
            updated_trait_table['CP6'] *
            (1 - math.exp(updated_trait_table['CP7'] * (1 - RA))))
        W_c = W_c_1 * W_c_2  # equation 62, weight of conceptus
        updated_trait_table['W_total'] = (
            updated_trait_table['weight'] + W_c)
    elif (cycle_month_index <
            (months_of_pregnancy +
                updated_trait_table['lactation_duration'])):
        # animal is lactating
        updated_trait_table['reproductive_status_int'] = 2
        updated_trait_table['W_total'] = updated_trait_table['weight']
        updated_trait_table['A_y'] = (
            (cycle_month_index - months_of_pregnancy) * 30 + 1)
    else:
        # animal is not pregnant or lactating
        updated_trait_table['reproductive_status_int'] = 0
        updated_trait_table['W_total'] = updated_trait_table['weight']
        updated_trait_table['A_foet'] = 0
        updated_trait_table['A_y'] = 0
    return updated_trait_table