package ru.yandex.direct.web.entity.campaign.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import ru.yandex.direct.core.entity.campaign.container.DeleteCampMetrikaCountersRequest;
import ru.yandex.direct.core.entity.campaign.container.UpdateCampMetrikaCountersRequest;
import ru.yandex.direct.core.entity.campaign.service.CampMetrikaCountersService;
import ru.yandex.direct.core.security.DirectAuthentication;
import ru.yandex.direct.dbutil.model.ClientId;
import ru.yandex.direct.operation.Applicability;
import ru.yandex.direct.result.Result;
import ru.yandex.direct.web.core.model.WebResponse;
import ru.yandex.direct.web.core.model.WebSuccessResponse;
import ru.yandex.direct.web.core.security.DirectWebAuthenticationSource;
import ru.yandex.direct.web.entity.campaign.model.DeleteCampMetrikaCountersWebRequest;
import ru.yandex.direct.web.entity.campaign.model.UpdateCampMetrikaCountersWebRequest;
import ru.yandex.direct.web.validation.kernel.ValidationResultConversionService;

import static ru.yandex.direct.core.validation.ValidationUtils.hasValidationIssues;


@Service
public class WebCampMetrikaCountersService {
    private static final Logger logger = LoggerFactory.getLogger(WebCampMetrikaCountersService.class);

    private final DirectWebAuthenticationSource authenticationSource;
    private final ValidationResultConversionService validationResultConversionService;
    private final CampMetrikaCountersService campMetrikaCountersService;


    @Autowired
    public WebCampMetrikaCountersService(
            DirectWebAuthenticationSource authenticationSource,
            ValidationResultConversionService validationResultConversionService,
            CampMetrikaCountersService campMetrikaCountersService) {
        this.authenticationSource = authenticationSource;
        this.validationResultConversionService = validationResultConversionService;
        this.campMetrikaCountersService = campMetrikaCountersService;
    }


    public WebResponse addCampMetrikaCounters(UpdateCampMetrikaCountersWebRequest webRequest) {
        DirectAuthentication authentication = authenticationSource.getAuthentication();
        ClientId clientId = authentication.getSubjectUser().getClientId();
        logger.debug("uid: {}, clientId: {}", authentication.getSubjectUser().getUid(), clientId);

        UpdateCampMetrikaCountersRequest modelRequest = convertUpdateWebRequestToModel(webRequest);

        Result<UpdateCampMetrikaCountersRequest> operationResult =
                campMetrikaCountersService.addCampMetrikaCounters(clientId, modelRequest, Applicability.PARTIAL);
        if (hasValidationIssues(operationResult)) {
            return validationResultConversionService.buildValidationResponse(operationResult);
        }
        return new WebSuccessResponse();
    }


    public WebResponse replaceCampMetrikaCounters(UpdateCampMetrikaCountersWebRequest webRequest) {
        DirectAuthentication authentication = authenticationSource.getAuthentication();
        ClientId clientId = authentication.getSubjectUser().getClientId();
        logger.debug("uid: {}, clientId: {}", authentication.getSubjectUser().getUid(), clientId);

        UpdateCampMetrikaCountersRequest modelRequest = convertUpdateWebRequestToModel(webRequest);

        Result<UpdateCampMetrikaCountersRequest> operationResult =
                campMetrikaCountersService.replaceCampMetrikaCounters(clientId, modelRequest, Applicability.PARTIAL);
        if (hasValidationIssues(operationResult)) {
            return validationResultConversionService.buildValidationResponse(operationResult);
        }
        return new WebSuccessResponse();
    }


    public WebResponse deleteCampMetrikaCounters(DeleteCampMetrikaCountersWebRequest webRequest) {
        DirectAuthentication authentication = authenticationSource.getAuthentication();
        ClientId clientId = authentication.getSubjectUser().getClientId();
        logger.debug("uid: {}, clientId: {}", authentication.getSubjectUser().getUid(), clientId);

        DeleteCampMetrikaCountersRequest modelRequest = convertDeleteWebRequestToModel(webRequest);

        Result<DeleteCampMetrikaCountersRequest> operationResult =
                campMetrikaCountersService.deleteAllCampMetrikaCounters(clientId, modelRequest, Applicability.PARTIAL);
        if (hasValidationIssues(operationResult)) {
            return validationResultConversionService.buildValidationResponse(operationResult);
        }
        return new WebSuccessResponse();
    }


    private UpdateCampMetrikaCountersRequest convertUpdateWebRequestToModel(
            UpdateCampMetrikaCountersWebRequest request) {
        return new UpdateCampMetrikaCountersRequest()
                .withCids(request.getCids())
                .withMetrikaCounters(request.getMetrikaCounters());
    }


    private DeleteCampMetrikaCountersRequest convertDeleteWebRequestToModel(
            DeleteCampMetrikaCountersWebRequest request) {
        return new DeleteCampMetrikaCountersRequest().withCids(request.getCids());
    }
}
