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

import java.util.List;

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

import com.yandex.direct.api.v5.dynamictextadtargets.DeleteRequest;
import com.yandex.direct.api.v5.dynamictextadtargets.DeleteResponse;
import com.yandex.direct.api.v5.general.ActionResult;
import com.yandex.direct.api.v5.general.IdsCriteria;
import org.springframework.stereotype.Component;

import ru.yandex.direct.api.v5.converter.ResultConverter;
import ru.yandex.direct.api.v5.entity.BaseApiServiceDelegate;
import ru.yandex.direct.api.v5.entity.dynamictextadtargets.DynamicAdTargetsDefectTypes;
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.constraints.Constraints;
import ru.yandex.direct.core.entity.dynamictextadtarget.service.DynamicTextAdTargetService;
import ru.yandex.direct.dbutil.model.ClientId;
import ru.yandex.direct.result.MassResult;
import ru.yandex.direct.validation.builder.ItemValidationBuilder;
import ru.yandex.direct.validation.result.PathConverter;
import ru.yandex.direct.validation.result.ValidationResult;

import static ru.yandex.direct.api.v5.entity.dynamictextadtargets.validation.DynamicTextAdTargetsDefectPresentations.DEFECT_PRESENTATIONS_HOLDER;
import static ru.yandex.direct.api.v5.validation.constraints.Constraints.eachNotNull;
import static ru.yandex.direct.utils.FunctionalUtils.mapList;

@ParametersAreNonnullByDefault
@Component
public class DeleteDynamicTextAdTargetsDelegate extends BaseApiServiceDelegate<DeleteRequest, DeleteResponse, List<Long>, ApiResult<Long>> {

    private final DynamicTextAdTargetService dynamicTextAdTargetService;
    private final ResultConverter resultConverter;

    public static final int MAX_IDS_PER_DELETE = 10_000;

    public DeleteDynamicTextAdTargetsDelegate(ApiAuthenticationSource auth,
                                              DynamicTextAdTargetService dynamicTextAdTargetService,
                                              ResultConverter resultConverter) {
        super(PathConverter.identity(), auth);
        this.dynamicTextAdTargetService = dynamicTextAdTargetService;
        this.resultConverter = resultConverter;
    }

    @Nullable
    @Override
    public ValidationResult<DeleteRequest, DefectType> validateRequest(DeleteRequest request) {
        ItemValidationBuilder<DeleteRequest, DefectType> vb = ItemValidationBuilder.of(request);
        vb.item(request.getSelectionCriteria(),
                DeleteRequest.PropInfo.SELECTION_CRITERIA.schemaName.getLocalPart())
                .item(request.getSelectionCriteria().getIds(), IdsCriteria.PropInfo.IDS.schemaName.getLocalPart())
                .check(eachNotNull())
                .check(Constraints.maxListSize(MAX_IDS_PER_DELETE),
                        DynamicAdTargetsDefectTypes.maxElementsPerDynamicAdTargetsDelete(MAX_IDS_PER_DELETE));
        return vb.getResult();
    }

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

    @Override
    public ApiResult<List<ApiResult<Long>>> processRequest(List<Long> dynamicTextAdTargetIds) {
        ClientId clientId = auth.getChiefSubclient().getClientId();
        Long operatorUid = auth.getOperator().getUid();
        MassResult<Long> result =
                dynamicTextAdTargetService.deleteDynamicAdTargets(operatorUid, clientId, dynamicTextAdTargetIds);
        return resultConverter.toApiMassResult(result, DEFECT_PRESENTATIONS_HOLDER);
    }

    @Override
    public DeleteResponse convertResponse(ApiResult<List<ApiResult<Long>>> result) {
        List<ActionResult> deleteResults =
                mapList(result.getResult(), r -> resultConverter.convertToActionResult(r, apiPathConverter));

        return new DeleteResponse().withDeleteResults(deleteResults);
    }
}
