package ru.yandex.canvas.service.multitype.singletype;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import ru.yandex.canvas.model.CreativeWithId;
import ru.yandex.canvas.service.RTBHostExportService;
import ru.yandex.canvas.service.multitype.OnCreativeOperationResult;
import ru.yandex.canvas.service.multitype.SingleCreativeTypeIdsOperation;
import ru.yandex.canvas.service.multitype.singletype.request.SingleCreativeTypeOperationRequest;
import ru.yandex.canvas.service.rtbhost.RtbHostUploadHelper;

public abstract class SendToRtbHostBaseOperation<T extends CreativeWithId>
        extends SingleCreativeTypeIdsOperation<T, SingleCreativeTypeOperationRequest> {
    private final RtbHostUploadHelper<T> rtbHostUploadHelper;
    private final RTBHostExportService rtbHostExportService;

    public SendToRtbHostBaseOperation(RtbHostUploadHelper<T> rtbHostUploadHelper,
                                      RTBHostExportService rtbHostExportService) {
        this.rtbHostUploadHelper = rtbHostUploadHelper;
        this.rtbHostExportService = rtbHostExportService;
    }

    @Override
    public List<OnCreativeOperationResult> process(List<T> creatives) {
        List<OnCreativeOperationResult> result = new ArrayList<>();
        Map<T, String> invalidCreativesErrorMessages = Map.of();
        String errorMessage = null;
        try {
            invalidCreativesErrorMessages =
                    rtbHostExportService.exportValidCreativesToRtbHost(creatives, rtbHostUploadHelper);

            var validCreatives = new ArrayList<>(creatives);
            validCreatives.removeAll(invalidCreativesErrorMessages.keySet());
            onSuccess(validCreatives);
        } catch (Exception e) {
            getLogger().error("Error while sending creatives to RtbHost: ", e);
            errorMessage = "Rtb host export failed: " + e.getCause();
        }

        OnCreativeOperationResult opResult = errorMessage == null
                ? OnCreativeOperationResult.ok()
                : OnCreativeOperationResult.error(errorMessage);

        for (var creative : creatives) {
            var onCreativeOperationResult = invalidCreativesErrorMessages.containsKey(creative)
                    ? OnCreativeOperationResult.error(invalidCreativesErrorMessages.get(creative))
                    : opResult;
            result.add(onCreativeOperationResult);
        }

        return result;
    }

    public void onSuccess(List<T> creatives) {
        //do nothing
    }
}
