package ru.yandex.autotests.directapi.agencyclients.get;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;

import com.yandex.direct.api.v5.agencyclients.AgencyClientFieldEnum;
import com.yandex.direct.api.v5.agencyclients.GetResponse;
import com.yandex.direct.api.v5.general.CurrencyEnum;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import ru.yandex.aqua.annotations.project.Aqua;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.AccountScoreRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.ClientsRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.UsersRecord;
import ru.yandex.autotests.direct.db.steps.DirectJooqDbSteps;
import ru.yandex.autotests.direct.utils.money.Currency;
import ru.yandex.autotests.directapi.agencyclients.AgencyClientsFeatures;
import ru.yandex.autotests.directapi.agencyclients.AgencyClientsLogins;
import ru.yandex.autotests.directapi.apiclient.config.Semaphore;
import ru.yandex.autotests.directapi.model.api5.agencyclients.GetRequestMap;
import ru.yandex.autotests.directapi.model.api5.generalclients.ClientGetItemMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Step;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static ru.yandex.autotests.directapi.matchers.beandiffer2.BeanDifferMatcherV5.beanDifferV5;
import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;

@Aqua.Test
@Features(AgencyClientsFeatures.GET)
@Description("Проверка получения 'простых' (не вычисляемых) полей")
@RunWith(Parameterized.class)
public class GetSimpleFieldsTest {
    private static final String PATTERN = "yyyy-MM-dd";

    @ClassRule
    public static ApiSteps api = new ApiSteps();

    @ClassRule
    public static SemaphoreRule semaphore = Semaphore.getSemaphore();

    private ClientGetItemMap expectedResults;
    private AgencyClientFieldEnum[] simpleFields = new AgencyClientFieldEnum[]{
            AgencyClientFieldEnum.LOGIN,
            AgencyClientFieldEnum.CLIENT_ID,
            AgencyClientFieldEnum.CLIENT_INFO,
            AgencyClientFieldEnum.COUNTRY_ID,
            AgencyClientFieldEnum.PHONE,
            AgencyClientFieldEnum.CURRENCY,
            AgencyClientFieldEnum.CREATED_AT,
            AgencyClientFieldEnum.ACCOUNT_QUALITY
    };

    @Parameterized.Parameter
    public String agencyLogin;

    @Parameterized.Parameter(1)
    public String subclientLogin;

    @Parameterized.Parameter(2)
    public Currency currency;

    @Parameterized.Parameters(name = "Агентство - {0}, субклиент - {1}, валюта - {2}")
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][]{
                {AgencyClientsLogins.AGENCY_RUB, AgencyClientsLogins.AGENCY_RUB_SUBCLIENT, Currency.RUB},
                {AgencyClientsLogins.AGENCY_UAH, AgencyClientsLogins.AGENCY_UAH_SUBCLIENT, Currency.UAH},
                {AgencyClientsLogins.AGENCY_EUR, AgencyClientsLogins.AGENCY_EUR_SUBCLIENT, Currency.EUR},
                {AgencyClientsLogins.AGENCY_TRY, AgencyClientsLogins.AGENCY_TRY_SUBCLIENT, Currency.TRY}
        });
    }

    @Before
    @Step("Подготовка тестовых данных")
    public void prepare() {
        api.as(agencyLogin);

        DirectJooqDbSteps dbSteps = api.userSteps.getDirectJooqDbSteps().useShardForLogin(subclientLogin);

        UsersRecord usersRecord = dbSteps.usersSteps().getUser(subclientLogin);

        ClientsRecord clientsRecord = dbSteps.clientsSteps().getClients(usersRecord.getClientid());

        AccountScoreRecord accountScoreRecord =
                dbSteps.accountScoreSteps().getLastAccountScore(usersRecord.getClientid());
        BigDecimal expectedAccountScore =
                accountScoreRecord == null ? null : accountScoreRecord.getScore().stripTrailingZeros();

        String expectedCreatedAt =
                DateTimeFormat.forPattern(PATTERN).print(new DateTime(usersRecord.getCreatetime() * 1000));

        CurrencyEnum expectedCurrency = CurrencyEnum.fromValue(currency.value());

        Long countryId = clientsRecord.getCountryRegionId();

        String phone = usersRecord.getPhone();

        expectedResults = new ClientGetItemMap()
                .withLogin(subclientLogin)
                .withClientId(usersRecord.getClientid())
                .withCreatedAt(expectedCreatedAt)
                .withCurrency(expectedCurrency)
                .withPhone(phone == null ? "" : phone)
                .withAccountQuality(expectedAccountScore)
                .withClientInfo(usersRecord.getFio())
                .withCountryId(countryId.intValue());

        api.userSteps.clientFakeSteps().fakeClearClientSpentUnits(agencyLogin);
    }

    @Test
    public void getSimpleFieldsTest() {
        GetResponse getResponse =
                api.userSteps.agencyClientsStepsV5().agencyClientsGet(
                        new GetRequestMap().withSubclientLogins(subclientLogin).withFieldNames(simpleFields));

        assertThat("полученные поля совпадают с ожидаемыми", getResponse.getClients(),
                beanDifferV5(Collections.singletonList(expectedResults.getBean())));
    }
}

