package ru.yandex.webmaster3.viewer.http.achievements;

import java.util.Comparator;
import java.util.List;

import com.google.common.base.Strings;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.host.service.HostOwnerService;
import ru.yandex.webmaster3.core.http.Action;
import ru.yandex.webmaster3.core.http.ReadAction;
import ru.yandex.webmaster3.core.metrics.Category;
import ru.yandex.webmaster3.core.util.IdUtils;
import ru.yandex.webmaster3.storage.achievements.dao.AchievementsCHDao;
import ru.yandex.webmaster3.storage.achievements.dao.AchievementsData;
import ru.yandex.webmaster3.storage.achievements.model.AchievementInfo;
import ru.yandex.webmaster3.storage.achievements.model.AchievementInfo.OfficialAchievementInfo;
import ru.yandex.webmaster3.storage.achievements.model.AchievementProblem;
import ru.yandex.webmaster3.storage.achievements.model.AchievementService;
import ru.yandex.webmaster3.storage.achievements.model.AchievementTld;
import ru.yandex.webmaster3.storage.achievements.model.AchievementType;
import ru.yandex.webmaster3.storage.achievements.model.official.AchievementOfficialType;
import ru.yandex.webmaster3.storage.iks.IksService;
import ru.yandex.webmaster3.storage.services.MarketRatingInfo;
import ru.yandex.webmaster3.storage.services.ServiceInfo;
import ru.yandex.webmaster3.storage.services.SiteServiceType;
import ru.yandex.webmaster3.storage.services.SiteServicesCHDao;
import ru.yandex.webmaster3.storage.services.VerticalShareRatingInfo;

/**
 * Created by Oleg Bazdyrev on 24/08/2018.
 */
@ReadAction
@Category("achievements")
@Description("Получение ачивок хоста")
@AllArgsConstructor(onConstructor_ = @Autowired)
@Slf4j
public class GetAchievementsAction extends Action<GetAchievementsRequest, GetAchievementsResponse> {

    private final AchievementsCHDao mdbAchievementsCHDao;
    private final SiteServicesCHDao mdbSiteServicesCHDao;
    private final IksService iksService;
    private final AchievementService achievementService;
    private final HostOwnerService hostOwnerService;

    @Override
    public GetAchievementsResponse process(GetAchievementsRequest request) throws WebmasterException {
        WebmasterHostId hostId;
        String owner = "";
        try {
            hostId = IdUtils.urlToHostId(request.getHost());
            owner = hostOwnerService.getMascotHostOwner(hostId.getPunycodeHostname());
        } catch (WebmasterException | IllegalArgumentException | NullPointerException ignored) {
        }

        AchievementsData pair =
                mdbAchievementsCHDao.getAchievementsAndProblems(request.getTld(), owner);
        List<AchievementInfo> achievements = pair.getInfos();
        // adding IKS, market rating, vertical share rating and is validated
        if (request.getTld() == AchievementTld.RU && !Strings.isNullOrEmpty(owner)) {
            int iks = iksService.getIksValueForOwner(owner);
            achievements.add(new AchievementInfo.SqiAchievementInfo(null, null, iks));

            var siteServiceTypeToInfo = mdbSiteServicesCHDao.getSiteServiceInfo(owner);
//            market rating
            ServiceInfo mbMarketRating = siteServiceTypeToInfo.get(SiteServiceType.MARKET_RATING);
            if (mbMarketRating != null) {
                MarketRatingInfo rating = (MarketRatingInfo) mbMarketRating;
                achievements.add(new AchievementInfo.MarketRatingInfo(rating.getId(), rating.getRating()));
            }
//          vertical share rating
            ServiceInfo mbVerticalShareRating = siteServiceTypeToInfo.get(SiteServiceType.VERTICAL_SHARE_RATING);
            if (mbVerticalShareRating != null) {
                VerticalShareRatingInfo rating = (VerticalShareRatingInfo) mbVerticalShareRating;
                achievements.add(new AchievementInfo.VerticalShareRatingInfo(rating.getRating()));
            }
        }
        // если сервис Яндекс - выкинем остальные ачивки
        OfficialAchievementInfo offInfo = (OfficialAchievementInfo)
                achievements.stream().filter(info -> info.getType() == AchievementType.OFFICIAL).findAny().orElse(null);

        if (offInfo != null && offInfo.getValue().contains(AchievementOfficialType.YANDEX)) {
            achievements.clear();
            achievements.add(offInfo);
        }

        achievements.sort(Comparator.comparing(AchievementInfo::getType));

        // проблемы
        List<AchievementProblem> problems = pair.getProblems();
        return new GetAchievementsResponse(owner, achievements, problems, request.getTld().isCanHaveTld(),
                achievementService.getAllAchievementTypes(request.getTld()));
    }
}
