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

import java.util.List;

import com.yandex.direct.api.v5.general.ActionResult;
import com.yandex.direct.api.v5.retargetinglists.DeleteRequest;
import com.yandex.direct.api.v5.retargetinglists.DeleteResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.BaseApiServiceDelegate;
import ru.yandex.direct.api.v5.entity.retargetinglists.RetargetingListsTranslations;
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.core.entity.retargeting.service.RetargetingConditionOperationFactory;
import ru.yandex.direct.dbutil.model.ClientId;
import ru.yandex.direct.i18n.types.Identity;
import ru.yandex.direct.validation.builder.ItemValidationBuilder;
import ru.yandex.direct.validation.result.ValidationResult;

import static ru.yandex.direct.api.v5.entity.retargetinglists.Constants.MAX_IDS_PER_DELETE;
import static ru.yandex.direct.api.v5.validation.constraints.Constraints.maxListSize;
import static ru.yandex.direct.utils.FunctionalUtils.mapList;

@Service
public class DeleteRetargetingListsDelegate extends
        BaseApiServiceDelegate<DeleteRequest, DeleteResponse, List<Long>, ApiResult<Long>> {
    private static final DefectType DELETE_MAX_IDS_DETAILED = DefectTypes.maxIdsInSelection().withDetailedMessage(
            RetargetingListsTranslations.INSTANCE.deleteMaxIdsDetailed(new Identity(MAX_IDS_PER_DELETE)));

    private static final Logger logger = LoggerFactory.getLogger(DeleteRetargetingListsDelegate.class);

    private final RetargetingConditionOperationFactory retargetingConditionOperationFactory;
    private final ResultConverter resultConverter;

    @Autowired
    public DeleteRetargetingListsDelegate(
            ApiAuthenticationSource auth,
            RetargetingConditionOperationFactory retargetingConditionOperationFactory,
            ResultConverter resultConverter) {
        super(ApiPathConverter.forRetargetingLists(), auth);
        this.retargetingConditionOperationFactory = retargetingConditionOperationFactory;
        this.resultConverter = resultConverter;
    }

    @Override
    public ValidationResult<DeleteRequest, DefectType> validateRequest(DeleteRequest externalRequest) {
        ItemValidationBuilder<DeleteRequest, DefectType> vb = ItemValidationBuilder.of(externalRequest);
        vb.item(externalRequest.getSelectionCriteria(), "SelectionCriteria")
                .item(externalRequest.getSelectionCriteria().getIds(), "Ids")
                .check(maxListSize(MAX_IDS_PER_DELETE), DELETE_MAX_IDS_DETAILED);
        return vb.getResult();
    }

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

    @Override
    public ApiMassResult<Long> processRequest(List<Long> request) {
        ClientId clientId = auth.getChiefSubclient().getClientId();
        return resultConverter.toApiMassResult(retargetingConditionOperationFactory.deleteRetargetingConditions(request, clientId));
    }

    @Override
    public DeleteResponse convertResponse(ApiResult<List<ApiResult<Long>>> result) {
        List<ActionResult> deleteResults =
                mapList(result.getResult(), r -> resultConverter.convertToActionResult(r, apiPathConverter));
        logger.trace("Return Delete-response");
        return new DeleteResponse().withDeleteResults(deleteResults);
    }
}
