package ru.yandex.webmaster3.viewer.http.turbo.statistics;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.google.common.base.Strings;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import ru.yandex.autodoc.common.doc.annotation.Category;
import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.core.http.ActionResponse;
import ru.yandex.webmaster3.core.http.ReadAction;
import ru.yandex.webmaster3.core.turbo.model.TurboAutoRelatedSettings;
import ru.yandex.webmaster3.core.turbo.model.TurboHostHeader;
import ru.yandex.webmaster3.core.turbo.model.TurboHostHeaderType;
import ru.yandex.webmaster3.core.turbo.model.TurboHostSettings;
import ru.yandex.webmaster3.core.turbo.model.TurboType;
import ru.yandex.webmaster3.core.turbo.model.advertising.AdvertisingPlacement;
import ru.yandex.webmaster3.core.turbo.model.advertising.AdvertisingSettings;
import ru.yandex.webmaster3.core.turbo.model.comments.TurboCommentsSettings;
import ru.yandex.webmaster3.core.turbo.model.desktop.TurboDesktopSettings;
import ru.yandex.webmaster3.core.turbo.model.feedback.TurboFeedbackSettings;
import ru.yandex.webmaster3.core.turbo.model.search.TurboSearchSettings;
import ru.yandex.webmaster3.core.util.WwwUtil;
import ru.yandex.webmaster3.storage.turbo.service.settings.TurboSettingsService;
import ru.yandex.webmaster3.viewer.http.AbstractUserVerifiedHostAction;
import ru.yandex.webmaster3.viewer.http.AbstractUserVerifiedHostRequest;

/**
 * ishalaru
 * 27.03.2020
 **/

@ReadAction
@Description(value = "Информацию о степени турбированности трафика сайта")
@Category("turbo")
@Component("/turbo/statistics/statuses")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class TurboStatusesAction extends AbstractUserVerifiedHostAction<TurboStatusesAction.Request, TurboStatusesAction.Response> {
    private final TurboSettingsService turboSettingsService;

    /*

    const newsRecommendations = [
    { type: 'reviews' },
    { type: 'autofeed' },
    { type: 'ads' },
    { type: 'ads-autoplacement' },
    { type: 'analytics-counters' },
    { type: 'css' },
    { type: 'feedback' },
    { type: 'main' },
    { type: 'header-logo' },
    { type: 'menu' },
    { type: 'turbo-desktop' },
];

const ecommerceRecommendations = [
    { type: 'listings' },
    { type: 'shopping-cart' },
    { type: 'delivery' },
    { type: 'info-sections' },
    { type: 'search' },
    { type: 'user-agreement' },
];
     */
    @Override
    public Response process(Request request) {
        final String domain = WwwUtil.cutWWWAndM(request.getHostId());
        final TurboHostSettings settings = turboSettingsService.getSettings(domain);
        final TurboDesktopSettings desktopSettings = turboSettingsService.getDesktopSettings(domain);
        Map<String, Boolean> status = new HashMap<>();
        boolean desktopEnabled = Optional.ofNullable(desktopSettings).map(TurboDesktopSettings::getEnabled).orElse(false);
        final Boolean cmntStatus = Optional.ofNullable(settings.getCommentsSettings()).map(TurboCommentsSettings::getStatus).map(e -> e != null && TurboCommentsSettings.TURBO_COMMENT_STATUS.NO != e).orElse(false);
        status.put("reviews", cmntStatus);
        status.put("autofeed", Optional.ofNullable(settings.getAutoRelatedSettings()).map(TurboAutoRelatedSettings::isEnabled).orElse(settings.getAutoRelated()));
        boolean abs = !Optional.ofNullable(settings.getAdvertisingSettingsList()).map(List::isEmpty).orElse(true)
                || (desktopEnabled && !Optional.ofNullable(desktopSettings.getAdvertisingSettingsList()).map(List::isEmpty).orElse(true));
        status.put("ads", abs);
        status.put("ads-autoplacement", hasAutoAdvertising(settings.getAdvertisingSettings()) || (desktopEnabled && hasAutoAdvertising(desktopSettings.getAdvertisingSettings())));
        status.put("analytics-counters", !Optional.ofNullable(settings.getAnalyticsSettings()).map(List::isEmpty).orElse(true));
        status.put("css", !Strings.isNullOrEmpty(settings.getCss()) || (desktopEnabled && !Strings.isNullOrEmpty(desktopSettings.getCss())));
        status.put("feedback", !Optional.ofNullable(settings.getFeedbackSettings()).map(TurboFeedbackSettings::getButtons).map(List::isEmpty).orElse(true));
        status.put("main", settings.getAutoMorda());
        status.put("header-logo", checkHeader(settings.getHeader()) || (desktopEnabled && checkHeader(desktopSettings.getHeader())));
        status.put("menu", !Optional.ofNullable(settings.getMenuSettings()).map(List::isEmpty).orElse(true));
        status.put("turbo-desktop", desktopEnabled);
        status.put("search", Optional.ofNullable(settings.getSearchSettings()).map(TurboSearchSettings::getUrl).map(StringUtils::isNotBlank).orElse(false));

        return new Response(TurboType.CONTENT.toString(), status);
    }

    private boolean checkHeader(TurboHostHeader hostHeader) {
        if (hostHeader != null && hostHeader.getType() == TurboHostHeaderType.NOLOGO) {
            return !Strings.isNullOrEmpty(hostHeader.getTitle());
        }
        if (hostHeader != null && (hostHeader.getType() == TurboHostHeaderType.SQUARE || hostHeader.getType() == TurboHostHeaderType.HORIZONTAL)) {
            return hostHeader.getLogoInfo() != null && !Strings.isNullOrEmpty(hostHeader.getLogoInfo().getLogoId());
        }
        return hostHeader != null && !Strings.isNullOrEmpty(hostHeader.getTitle()) && hostHeader.getLogoInfo() != null && !Strings.isNullOrEmpty(hostHeader.getLogoInfo().getLogoId());
    }

    private boolean hasAutoAdvertising(Map<AdvertisingPlacement, List<AdvertisingSettings>> advertisingSettings) {
        if (advertisingSettings != null && advertisingSettings.size() > 0) {
            int count = advertisingSettings.size();
            count -= advertisingSettings.containsKey(AdvertisingPlacement.MANUAL) ? 1 : 0;
            count -= advertisingSettings.containsKey(AdvertisingPlacement.MANUAL_STICKY) ? 1 : 0;
            count -= advertisingSettings.containsKey(AdvertisingPlacement.MANUAL_TOP) ? 1 : 0;
            return count > 0;
        }
        return false;
    }

    public static class Request extends AbstractUserVerifiedHostRequest {
    }

    public static class Response implements ActionResponse.NormalResponse {
        @Getter
        private final String type;
        @Getter
        private final Map<String, Boolean> turboStatus;

        @JsonCreator
        public Response(String type, Map<String, Boolean> turboStatus) {
            this.type = type;
            this.turboStatus = turboStatus;
        }
    }
}
