package ru.yandex.webmaster3.storage.services;

import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ru.yandex.webmaster3.core.util.WwwUtil;
import ru.yandex.webmaster3.storage.metrika.dao.MetrikaCounterBindingStateYDao;
import ru.yandex.webmaster3.storage.metrika.dao.MetrikaCrawlStateYDao;
import ru.yandex.webmaster3.storage.metrika.data.MetrikaCounterCrawlStateEnum;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static ru.yandex.webmaster3.core.metrika.counters.CounterBindingStateEnum.APPROVED;

@Service
@AllArgsConstructor(onConstructor_ = @Autowired)
public class SiteServiceService {
    private final SiteServicesCHDao mdbSiteServicesCHDao;
    private final MetrikaCounterBindingStateYDao metrikaCounterBindingStateYDao;
    private final MetrikaCrawlStateYDao metrikaCrawlStateYDao;

    public Map<SiteServiceType, ServiceInfo> getRivalInfo(String rival, boolean isMyHost) {
        String domain = WwwUtil.cutWWWAndM(rival);
        Map<SiteServiceType, ServiceInfo> siteServiceInfo = mdbSiteServicesCHDao.getRivalServiceInfo(domain);

        if (isMyHost) {
            addMetrikaInfoToMyHost(domain, siteServiceInfo);
        }

        return siteServiceInfo;
    }

    public Map<String, Map<SiteServiceType, ServiceInfo>> getBatchRivalInfo(Collection<String> hosts, String myHost) {
        Set<String> domains = hosts.stream()
                .map(WwwUtil::cutWWWAndM)
                .collect(Collectors.toSet());

        var rivalServiceInfoByDomain =
                mdbSiteServicesCHDao.getRivalServiceInfo(domains);

        Map<String, Map<SiteServiceType, ServiceInfo>> rivalServiceInfoByHost = new HashMap<>();

        for (var host : hosts) {
            // пересобираем мапку из domain -> info в host -> info
            String domain = WwwUtil.cutWWWAndM(host);
            Map<SiteServiceType, ServiceInfo> siteServiceInfo = rivalServiceInfoByDomain.get(domain);
            rivalServiceInfoByHost.put(host, siteServiceInfo);

            if (myHost.equals(host)) {
                addMetrikaInfoToMyHost(domain, siteServiceInfo);
            }

        }
        return rivalServiceInfoByHost;
    }

    private void addMetrikaInfoToMyHost(String domain, Map<SiteServiceType, ServiceInfo> siteServiceInfo) {
        UseMetrikaInfo metrikaInfo = new UseMetrikaInfo(false);

        if (metrikaCounterBindingStateYDao.getAllForDomain(domain).stream().anyMatch(a -> a.getCounterBindingState() == APPROVED)) {
            metrikaInfo.setValue(true);
            if (metrikaCrawlStateYDao.getStatesForDomain(domain).stream().anyMatch(a -> a.getState() == MetrikaCounterCrawlStateEnum.ENABLED)) {
                metrikaInfo.setStatus(UseMetrikaInfo.MetrikaType.CRAWL_ENABLED);
            } else {
                metrikaInfo.setStatus(UseMetrikaInfo.MetrikaType.METRIKA_CONNECTED);
            }
        } else {
            metrikaInfo.setStatus(UseMetrikaInfo.MetrikaType.NONE);
        }

        siteServiceInfo.put(SiteServiceType.USE_METRIKA, metrikaInfo);
    }
}
