package ru.yandex.autotests.directapi.steps.clients;

import java.math.BigDecimal;

import javax.xml.bind.JAXBElement;

import com.yandex.direct.api.v5.clients.ClientFieldEnum;
import com.yandex.direct.api.v5.clients.GetRequest;
import com.yandex.direct.api.v5.clients.GetResponse;
import com.yandex.direct.api.v5.clients.UpdateResponse;
import com.yandex.direct.api.v5.generalclients.ClientGetItem;

import ru.yandex.autotests.directapi.apiclient.RequestHeader;
import ru.yandex.autotests.directapi.apiclient.config.ConnectionConfig;
import ru.yandex.autotests.directapi.apiclient.errors.Api5Error;
import ru.yandex.autotests.directapi.apiclient.version5.ServiceNames;
import ru.yandex.autotests.directapi.exceptions.DirectAPIException;
import ru.yandex.autotests.directapi.model.api5.Action;
import ru.yandex.autotests.directapi.model.api5.clients.GetRequestMap;
import ru.yandex.autotests.directapi.model.api5.clients.UpdateRequestMap;
import ru.yandex.autotests.directapi.steps.BaseApiSteps;
import ru.yandex.autotests.irt.testutils.allure.LogSteps;
import ru.yandex.qatools.allure.annotations.Step;

/**
 * Created by buhter on 10/02/16.
 */
public class ClientsStepsV5 extends BaseApiSteps {
    private LogSteps log = LogSteps.getLogger(this.getClass());

    private static ClientsStepsV5 _instance;

    private ClientsStepsV5(ConnectionConfig connectionConfig, RequestHeader requestHeader) {
        super(connectionConfig, requestHeader);
    }

    public static ClientsStepsV5 getInstance(ConnectionConfig connectionConfig, RequestHeader requestHeader) {
        if (_instance == null) {
            _instance = new ClientsStepsV5(connectionConfig, requestHeader);
        } else {
            _instance.setConnectionConfig(connectionConfig);
            _instance.setRequestHeader(requestHeader);
        }
        return _instance;
    }

    //region Get
    @Step("[Clients]: Get")
    public GetResponse clientsGet(GetRequestMap parameters, String login) {
        return defaultClientV5()
                .invokeMethod(ServiceNames.CLIENTS, login, Action.GET, (GetRequest) parameters.getBean());
    }

    public GetResponse clientsGet(GetRequestMap parameters) {
        return clientsGet(parameters, null);
    }

    public Double getClientVatRate(String login) {
        return clientsGet(new GetRequestMap().withFieldNames(ClientFieldEnum.VAT_RATE), login)
                .getClients()
                .stream()
                .findFirst()
                .map(ClientGetItem::getVatRate)
                .map(JAXBElement::getValue)
                .map(BigDecimal::doubleValue)
                .map(t -> t * 0.01)
                .orElseThrow(() -> new DirectAPIException("Указанный в тесте клиент " + login + " не найден"));
    }

    public void expectErrorOnClientsGet(GetRequestMap parameters, String login, Api5Error api5Error) {
        shouldGetErrorOn(ServiceNames.CLIENTS, login, Action.GET, parameters, api5Error);
    }

    public void expectErrorOnClientsGet(GetRequestMap parameters, Api5Error api5Error) {
        expectErrorOnClientsGet(parameters, null, api5Error);
    }

    //endregion

    @Step("[Clients]: Update")
    public UpdateResponse clientsUpdate(UpdateRequestMap parameters, String login) {
        return defaultClientV5().invokeMethod(ServiceNames.CLIENTS, login, Action.UPDATE, parameters.getBean());
    }

    public UpdateResponse clientsUpdate(UpdateRequestMap parameters) {
        return clientsUpdate(parameters, null);
    }

    public void expectErrorOnClientsUpdate(UpdateRequestMap parameters, String login, Api5Error api5Error) {
        shouldGetErrorOn(ServiceNames.CLIENTS, login, Action.UPDATE, parameters, api5Error);
    }

    public void expectErrorOnClientsUpdate(UpdateRequestMap parameters, Api5Error api5Error) {
        expectErrorOnClientsUpdate(parameters, null, api5Error);
    }
}
