package ru.yandex.direct.api.v5.entity.smartadtargets.delegate;

import java.util.List;
import java.util.Set;

import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;

import com.yandex.direct.api.v5.smartadtargets.GetRequest;
import com.yandex.direct.api.v5.smartadtargets.GetResponse;
import com.yandex.direct.api.v5.smartadtargets.SmartAdTargetFieldEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import ru.yandex.direct.api.v5.common.ApiPathConverter;
import ru.yandex.direct.api.v5.entity.GenericGetRequest;
import ru.yandex.direct.api.v5.entity.GetApiServiceDelegate;
import ru.yandex.direct.api.v5.entity.smartadtargets.converter.GetRequestConverter;
import ru.yandex.direct.api.v5.entity.smartadtargets.converter.GetResponseConverterService;
import ru.yandex.direct.api.v5.entity.smartadtargets.validation.SmartAdTargetValidationService;
import ru.yandex.direct.api.v5.security.ApiAuthenticationSource;
import ru.yandex.direct.api.v5.validation.DefectType;
import ru.yandex.direct.core.entity.performancefilter.container.PerformanceFilterSelectionCriteria;
import ru.yandex.direct.core.entity.performancefilter.model.PerformanceFilter;
import ru.yandex.direct.core.entity.performancefilter.service.PerformanceFilterService;
import ru.yandex.direct.dbutil.model.ClientId;
import ru.yandex.direct.validation.result.ValidationResult;

@Service
@ParametersAreNonnullByDefault
public class GetSmartAdTargetDelegate
        extends GetApiServiceDelegate<GetRequest,
        GetResponse,
        SmartAdTargetFieldEnum,
        PerformanceFilterSelectionCriteria,
        PerformanceFilter> {

    private final SmartAdTargetValidationService validationService;
    private final PerformanceFilterService performanceFilterService;
    private final GetResponseConverterService responseConverterService;

    @Autowired
    public GetSmartAdTargetDelegate(ApiAuthenticationSource apiAuthenticationSource,
                                    SmartAdTargetValidationService validationService,
                                    PerformanceFilterService performanceFilterService,
                                    GetResponseConverterService responseConverterService) {
        super(ApiPathConverter.forSmartadtargets(), apiAuthenticationSource);
        this.validationService = validationService;
        this.performanceFilterService = performanceFilterService;
        this.responseConverterService = responseConverterService;
    }

    @Nullable
    @Override
    public ValidationResult<GetRequest, DefectType> validateRequest(GetRequest getRequest) {
        return validationService.validateGetRequest(getRequest);
    }

    @Override
    public Set<SmartAdTargetFieldEnum> extractFieldNames(GetRequest externalRequest) {
        return GetRequestConverter.getSmartAdTargetFieldEnums(externalRequest);
    }

    @Override
    public PerformanceFilterSelectionCriteria extractSelectionCriteria(GetRequest getRequest) {
        return GetRequestConverter.convert(getRequest);
    }

    @Override
    public List<PerformanceFilter> get(GenericGetRequest<SmartAdTargetFieldEnum, PerformanceFilterSelectionCriteria> getRequest) {
        ClientId clientId = auth.getChiefSubclient().getClientId();
        Long operatorUid = auth.getOperator().getUid();
        PerformanceFilterSelectionCriteria selectionCriteria = getRequest.getSelectionCriteria()
                .withLimitOffset(getRequest.getLimitOffset());
        return performanceFilterService.getPerfFiltersBySelectionCriteria(clientId, operatorUid, selectionCriteria);
    }

    @Override
    public GetResponse convertGetResponse(List<PerformanceFilter> filters,
                                          Set<SmartAdTargetFieldEnum> requestedFields, @Nullable Long limitedBy) {
        ClientId clientId = auth.getChiefSubclient().getClientId();
        return responseConverterService.getGetResponse(clientId, filters, requestedFields, limitedBy);
    }

}
