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

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

import javax.annotation.Nonnull;

import com.yandex.direct.api.v5.audiencetargets.SuspendRequest;
import com.yandex.direct.api.v5.audiencetargets.SuspendResponse;
import com.yandex.direct.api.v5.general.ActionResult;
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.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.api.v5.validation.DefectTypes;
import ru.yandex.direct.common.db.PpcPropertiesSupport;
import ru.yandex.direct.core.entity.adgroup.model.AdGroupType;
import ru.yandex.direct.core.entity.adgroup.service.AdGroupService;
import ru.yandex.direct.core.entity.feature.service.FeatureService;
import ru.yandex.direct.core.entity.retargeting.service.RetargetingService;
import ru.yandex.direct.dbutil.model.ClientId;
import ru.yandex.direct.validation.builder.ItemValidationBuilder;
import ru.yandex.direct.validation.result.ValidationResult;

import static ru.yandex.direct.api.v5.entity.audiencetargets.Constants.MAX_IDS_PER_REQUEST;
import static ru.yandex.direct.api.v5.entity.audiencetargets.validation.AudienceTargetsAdGroupTypeConstraints.allowedAdGroupType;
import static ru.yandex.direct.api.v5.validation.constraints.Constraints.maxListSize;
import static ru.yandex.direct.utils.FunctionalUtils.mapList;

@Service
public class SuspendAudienceTargetsDelegate
        extends OperationOnListDelegate<SuspendRequest, SuspendResponse, Long, Long> {
    private final RetargetingService retargetingService;
    private final ResultConverter resultConverter;
    private final AdGroupService adGroupService;

    @Autowired
    public SuspendAudienceTargetsDelegate(ApiAuthenticationSource auth,
                                          RetargetingService retargetingService,
                                          ResultConverter resultConverter,
                                          AdGroupService adGroupService,
                                          PpcPropertiesSupport ppcPropertiesSupport,
                                          FeatureService featureService) {
        super(ApiPathConverter.forAudienceTargets(), auth, ppcPropertiesSupport, featureService);
        this.retargetingService = retargetingService;
        this.resultConverter = resultConverter;
        this.adGroupService = adGroupService;
    }

    @Override
    public ValidationResult<SuspendRequest, DefectType> validateRequest(SuspendRequest request) {
        ItemValidationBuilder<SuspendRequest, DefectType> vb = ItemValidationBuilder.of(request);
        vb.item(request.getSelectionCriteria(), "SelectionCriteria")
                .item(request.getSelectionCriteria().getIds(), "Ids")
                .check(maxListSize(MAX_IDS_PER_REQUEST),
                        DefectTypes.maxElementsPerRequest(MAX_IDS_PER_REQUEST));
        return vb.getResult();
    }

    @Override
    public List<Long> convertRequest(SuspendRequest externalRequest) {
        return externalRequest.getSelectionCriteria().getIds();
    }

    @Nonnull
    @Override
    public ValidationResult<List<Long>, DefectType> validateInternalRequest(List<Long> internalRequest) {
        Set<AdGroupType> allowedAdGroupTypes = getAllowedAdGroupTypes();
        return allowedAdGroupType(internalRequest, retargetingService, auth, adGroupService, allowedAdGroupTypes);
    }

    @Override
    public ApiMassResult<Long> processList(List<Long> validItems) {
        long operatorUid = auth.getOperator().getUid();
        ClientId clientId = auth.getChiefSubclient().getClientId();
        return resultConverter
                .toApiMassResult(retargetingService.suspendRetargetings(validItems, clientId, operatorUid));
    }

    @Override
    public SuspendResponse convertResponse(ApiResult<List<ApiResult<Long>>> result) {
        List<ActionResult> results = mapList(
                result.getResult(), r -> resultConverter.convertToActionResult(r, apiPathConverter));
        return new SuspendResponse().withSuspendResults(results);
    }
}
