import lusid


def set_transaction_mapping(client, transaction_mapping):
    """
    Sets the transaction mapping in LUSID so that the system can resolve the transactions into movements

    :param LusidApi client: The LusidApi client to use
    :param dict transaction_mapping: The transaction mapping configuration
    :return: ResourceListOfTransactionConfigurationData response: The response from LUSID
    """

    # Initialise your list of configuration requests, one for each transaction type
    configuration_requests = []

    # Iterate over your configurations in the default mapping
    for configuration in transaction_mapping['values']:

        # Initialise your list of aliases for this configuration
        aliases = []

        # Iterate over the aliases in the imported config
        for alias in configuration['aliases']:
            # Append the alias to your list
            aliases.append(
                lusid.models.TransactionConfigurationTypeAlias(
                    type=alias['type'],
                    description=alias['description'],
                    transaction_class=alias['transactionClass'],
                    transaction_group=alias['transactionGroup'],
                    transaction_roles=alias['transactionRoles']))

        # Initialise your list of movements for this configuration
        movements = []

        # Iterate over the movements in the impoted config
        for movement in configuration['movements']:

            # Add properties if they exist in the config
            if len(movement['properties']) > 0:
                key = movement['properties'][0]['key']
                value = lusid.models.PropertyValue(label_value=movement['properties'][0]['value'])
                properties = {
                    key: lusid.models.PerpetualProperty(key=key, value=value)
                }
            else:
                properties = {}

            if len(movement['mappings']) > 0:
                mappings = [
                    lusid.models.TransactionPropertyMappingRequest(
                        property_key=movement['mappings'][0]['propertyKey'],
                        set_to=movement['mappings'][0]['setTo'])
                ]
            else:
                mappings = []

            # Append the movement to your list
            movements.append(
                lusid.models.TransactionConfigurationMovementDataRequest(
                    movement_types=movement['movementTypes'],
                    side=movement['side'],
                    direction=movement['direction'],
                    properties=properties,
                    mappings=mappings))

        # Build your configuration for this transaction type
        configuration_requests.append(
            lusid.models.TransactionConfigurationDataRequest(
                aliases=aliases,
                movements=movements,
                properties=None))

    # Call LUSID to set your configuration for our transaction types
    response = client.system_configuration.set_configuration_transaction_types(
        types=configuration_requests)

    return response
