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

import java.util.List;

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

import com.yandex.direct.api.v5.feeds.UpdateRequest;
import com.yandex.direct.api.v5.feeds.UpdateResponse;
import one.util.streamex.StreamEx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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.feeds.converter.UpdateRequestConverter;
import ru.yandex.direct.api.v5.entity.feeds.validation.FeedsValidationService;
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.feed.model.Feed;
import ru.yandex.direct.core.entity.feed.service.FeedService;
import ru.yandex.direct.core.entity.user.model.ApiUser;
import ru.yandex.direct.dbutil.model.ClientId;
import ru.yandex.direct.model.ModelChanges;
import ru.yandex.direct.result.MassResult;
import ru.yandex.direct.validation.result.ValidationResult;

@Component
@ParametersAreNonnullByDefault
public class UpdateFeedsDelegate
        extends OperationOnListDelegate<UpdateRequest, UpdateResponse, ModelChanges<Feed>, Long> {

    private final FeedService feedService;
    private final ResultConverter resultConverter;

    @Autowired
    public UpdateFeedsDelegate(
            ApiAuthenticationSource auth,
            ResultConverter resultConverter,
            FeedService feedService,
            PpcPropertiesSupport ppcPropertiesSupport,
            FeatureService featureService) {
        super(ApiPathConverter.forFeeds(), auth, ppcPropertiesSupport, featureService);
        this.resultConverter = resultConverter;
        this.feedService = feedService;
    }

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

    @Override
    public List<ModelChanges<Feed>> convertRequest(UpdateRequest externalRequest) {
        return StreamEx.of(externalRequest.getFeeds())
                .map(UpdateRequestConverter::convert)
                .toList();
    }

    @Override
    public ApiMassResult<Long> processList(List<ModelChanges<Feed>> validItems) {
        ApiUser chiefSubclient = auth.getChiefSubclient();
        ClientId clientId = chiefSubclient.getClientId();
        Long clientUid = chiefSubclient.getUid();
        Long operatorUid = auth.getOperator().getUid();
        MassResult<Long> result = feedService.updateFeeds(clientId, clientUid, operatorUid, validItems);
        return resultConverter.toApiMassResult(result);
    }

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