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

import java.util.List;

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

import com.yandex.direct.api.v5.smartadtargets.UpdateRequest;
import com.yandex.direct.api.v5.smartadtargets.UpdateResponse;
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.converter.ResultConverter;
import ru.yandex.direct.api.v5.entity.OperationOnListDelegate;
import ru.yandex.direct.api.v5.entity.smartadtargets.converter.UpdateRequestConverterService;
import ru.yandex.direct.api.v5.entity.smartadtargets.validation.SmartAdTargetValidationService;
import ru.yandex.direct.api.v5.result.ApiMassResult;
import ru.yandex.direct.api.v5.result.ApiResult;
import ru.yandex.direct.api.v5.security.ApiAuthenticationSource;
import ru.yandex.direct.api.v5.validation.DefectType;
import ru.yandex.direct.common.db.PpcPropertiesSupport;
import ru.yandex.direct.core.entity.feature.service.FeatureService;
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.result.MassResult;
import ru.yandex.direct.validation.result.ValidationResult;

import static ru.yandex.direct.api.v5.entity.smartadtargets.defects.SmartAdTargetDefectTypes.DEFECT_PRESENTATIONS;

@Service
@ParametersAreNonnullByDefault
public class UpdateSmartAdTargetDelegate
        extends OperationOnListDelegate<UpdateRequest, UpdateResponse, PerformanceFilter, Long> {

    private final PerformanceFilterService performanceFilterService;
    private final UpdateRequestConverterService requestConverterService;
    private final ResultConverter resultConverter;
    private final SmartAdTargetValidationService validationService;

    @Autowired
    public UpdateSmartAdTargetDelegate(ApiAuthenticationSource apiAuthenticationSource,
                                       PerformanceFilterService performanceFilterService,
                                       UpdateRequestConverterService requestConverterService,
                                       ResultConverter resultConverter,
                                       SmartAdTargetValidationService validationService,
                                       PpcPropertiesSupport ppcPropertiesSupport,
                                       FeatureService featureService) {
        super(ApiPathConverter.forSmartadtargets(), apiAuthenticationSource, ppcPropertiesSupport, featureService);
        this.performanceFilterService = performanceFilterService;
        this.requestConverterService = requestConverterService;
        this.resultConverter = resultConverter;
        this.validationService = validationService;
    }

    @Nullable
    @Override
    public ValidationResult<UpdateRequest, DefectType> validateRequest(UpdateRequest externalRequest) {
        return validationService.validateUpdateRequest(externalRequest);
    }

    @Override
    public List<PerformanceFilter> convertRequest(UpdateRequest externalRequest) {
        ClientId clientId = auth.getChiefSubclient().getClientId();
        return requestConverterService.convertItemsToModels(clientId, externalRequest.getSmartAdTargets());
    }

    @Override
    public ApiMassResult<Long> processList(List<PerformanceFilter> performanceFiltersToUpdate) {
        Long operatorUid = auth.getOperator().getUid();
        ClientId clientId = auth.getChiefSubclient().getClientId();
        MassResult<Long> idsMassResult =
                performanceFilterService.updatePerformanceFilters(clientId, operatorUid, performanceFiltersToUpdate);
        return resultConverter.toApiMassResult(idsMassResult, DEFECT_PRESENTATIONS);
    }

    @Override
    public UpdateResponse convertResponse(ApiResult<List<ApiResult<Long>>> result) {
        return new UpdateResponse().withUpdateResults(resultConverter.toActionResults(result, apiPathConverter));
    }

}
