package ru.yandex.webmaster3.worker.digest;

import NWebmaster.proto.digest.Digest;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Required;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.digest.graphics.draw.ChartSettings;
import ru.yandex.webmaster3.core.notification.LanguageEnum;
import ru.yandex.webmaster3.core.util.IdUtils;
import ru.yandex.webmaster3.storage.digest.DigestMessage;
import ru.yandex.webmaster3.storage.user.notification.NotificationType;
import ru.yandex.webmaster3.worker.digest.graphics.draw.BuildClicksGraphicsUtil;
import ru.yandex.webmaster3.worker.digest.html.DigestData;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

@Slf4j
public class DigestTestHandler extends AbstractHandler {

    private DigestNotificationService digestNotificationService;
    private ChartSettings chartSettings;

    @Override
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        if (target.equals("/digest/templates")) {
            baseRequest.setHandled(true);
            String lang = baseRequest.getParameter("lang");
            String type = baseRequest.getParameter("type");

            openDigestTemplate(
                    lang == null ? LanguageEnum.DEFAULT_EMAIL_LANGUAGE : LanguageEnum.fromString(lang),
                    type == null ? NotificationType.DIGEST : NotificationType.valueOf(type),
                    response
            );
        }
    }

    private void openDigestTemplate(LanguageEnum lang, NotificationType digestType, HttpServletResponse response) throws IOException {

        String hostUrl = "https://сайт.рф";
        String hostBeautyUrlNew = "https://Сайт.рф";
        String owner = "сайт.рф";
        WebmasterHostId hostId = IdUtils.urlToHostId(hostUrl);
        long userId = 567768960;
        String email = "devnull@yandex-team.ru";
        LocalDate digestPeriodEnd = LocalDate.parse("2019-05-19");

        Digest.DigestWeeklyReportMessage digestReport = getDigestReport(hostUrl, hostBeautyUrlNew, owner);
        DigestMessage digestMessage = new DigestMessage(userId, hostId, email, lang, digestType, digestReport, digestPeriodEnd);
        Digest.DigestWeeklyReportMessage digest = digestReport;
        Digest.AllQueriesIndicators allQueries = digest.getAllQueries();
        Map<DigestAttachType, String> attaches = new EnumMap<>(DigestAttachType.class);

        if (digestNotificationService.clicksNewDataIsPresent(digest)) {
            List<Digest.ClicksByPeriod> oldData = new ArrayList<>();
            if (digestNotificationService.clicksOldDataIsPresent(digest)) {
                oldData = allQueries.getOldClicksByPeriodList();
            }
            byte[] clickDynamicsImage = BuildClicksGraphicsUtil.process(oldData, allQueries.getNewClicksByPeriodList(), chartSettings);
            attaches.put(DigestAttachType.CLICKS_DYNAMICS, "data:image/png;base64," + Base64.getEncoder().encodeToString(clickDynamicsImage));
        }

        DigestData renderData = digestNotificationService.createData(digestMessage);
        renderData.getChecklist().get().getEvents().add(new DigestData.YmlTurboAvailable(hostId));

        String digestHtml = digestNotificationService.buildHtml(digestMessage, renderData, attaches.keySet());
        for (var inline : attaches.entrySet()) {
            String inlineName = "cid:" + inline.getKey().getCid();
            digestHtml = digestHtml.replace(inlineName, inline.getValue());
            log.info("Inline {} {}", inlineName, inline.getValue().length());
        }

        response.setStatus(HttpServletResponse.SC_OK);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.print(digestHtml);
        writer.flush();
    }

    private Digest.DigestWeeklyReportMessage getDigestReport(String hostUrl1, String hostBeautyUrlNew, String owner) {
        return Digest.DigestWeeklyReportMessage.newBuilder()
                .setIks(getIKS(owner))
                .setBeautyUrls(getBeautyUrl(hostUrl1, hostBeautyUrlNew))
                .setRecommendedUrls(getRecommendedUrls())
                .setChecklist(getChecklistStatus())
                .setAllQueries(getAllQueries())
                .setGroupQueries(getQueryGroupsSamples())
                .setTopQueries(getTopQueriesSamples())
                .setGeoRegions(getGeoRegions())
                .setRecrawlUrls(getRecrawlUrls())
                .setSitetrees(getSitetree())
                .setAchievements(getAchievements())
                .setReviews(getReviews())
                .setMirrors(getMirror())
                .build();
    }

    private Digest.Sitetree getSitetree() {
        return Digest.Sitetree.newBuilder()
                .setOldState(Digest.SitetreeState.newBuilder()
                        .setNumOfDocs(1256488)
                        .setNumOfDocsOnSearch(1040513)
                        .setNewDocsOnSearch(2231)
                        .setGoneDocsOnSearch(3019)
                        .build()
                )
                .setNewState(Digest.SitetreeState.newBuilder()
                        .setNumOfDocs(1248929)
                        .setNumOfDocsOnSearch(1052636)
                        .setNewDocsOnSearch(7779)
                        .setGoneDocsOnSearch(602)
                        .build()
                )
                .addUrlHistory(Digest.SitetreeUrlHistory.newBuilder()
                        .setPath("/video/2018/05/31/")
                        .setUrlStatus(3)
                        .setTitle("Новости: 31.05.2018: Сайт.рф")
                        .setIsAdded(true)
                        .build()
                )
                .build();
    }

    private Digest.RecrawlUrls getRecrawlUrls() {
        return Digest.RecrawlUrls.newBuilder()
                .addNewState(Digest.RecrawlUrlState.newBuilder()
                        .setPath("/")
                        .setHttpCode(200)
                        .setSuccess(true)
                        .setTimestamp(1559171383)
                        .build())
                .build();
    }

    private Digest.GeoState getGeoRegions() {
        return Digest.GeoState.newBuilder()
                .setOldState(Digest.GeoWeekState.newBuilder()
                        .setVisible(true)
                        .setError("")
                        .addRegions(Digest.GeoRegionInfo.newBuilder().setRegionId(29).setSourceId(3).build())
                        .addRegions(Digest.GeoRegionInfo.newBuilder().setRegionId(29).setSourceId(4).build())
                        .addRegions(Digest.GeoRegionInfo.newBuilder().setRegionId(213).setSourceId(2).build())
                        .addRegions(Digest.GeoRegionInfo.newBuilder().setRegionId(11207).setSourceId(2).build())
                        .build()
                )
                .setNewState(Digest.GeoWeekState.newBuilder()
                        .setVisible(true)
                        .setError("")
                        .addRegions(Digest.GeoRegionInfo.newBuilder().setRegionId(29).setSourceId(3).build())
                        .addRegions(Digest.GeoRegionInfo.newBuilder().setRegionId(29).setSourceId(4).build())
                        .addRegions(Digest.GeoRegionInfo.newBuilder().setRegionId(213).setSourceId(2).build())
                        .build()
                )
                .addRegionsGone(Digest.GeoRegionInfo.newBuilder().setRegionId(11207).setSourceId(2).build())
                .addRegionsUnchanged(Digest.GeoRegionInfo.newBuilder().setRegionId(29).setSourceId(3).build())
                .addRegionsUnchanged(Digest.GeoRegionInfo.newBuilder().setRegionId(29).setSourceId(4).build())
                .addRegionsUnchanged(Digest.GeoRegionInfo.newBuilder().setRegionId(213).setSourceId(2).build())
                .build();
    }

    private Digest.IKS getIKS(String owner) {
        return Digest.IKS.newBuilder()
                .setOldState(Digest.IKSState.newBuilder().setIks(100).setTimestamp(1558040400).build())
                .setNewState(Digest.IKSState.newBuilder().setIks(200).setTimestamp(1557435600).build())
                .setOwner(owner)
                .build();
    }

    private Digest.BeautyUrlState getBeautyUrl(String hostUrl1, String hostBeautyUrlNew) {
        return Digest.BeautyUrlState.newBuilder()
                .setOldState(hostUrl1)
                .setNewState(hostBeautyUrlNew)
                .build();
    }

    private Digest.Reviews getReviews(){
        return Digest.Reviews.newBuilder().setCountNew(10).setCountOld(5).build();
    }

    private Digest.Mirrors getMirror(){
        return Digest.Mirrors.newBuilder().setMainMirror("http://сайт.рф").build();
    }

    private Digest.Achievements getAchievements(){
        var builder = Digest.Achievements.newBuilder()
                .addAchievementsOld(Digest.AchievementsSnapshot.newBuilder()
                        .setHttps(false)
                        .setTurbo(false)
                        .setSpeedGradeMobile(1)
                        .setTld("ru")
                        .build())
                .addAchievementsNew(Digest.AchievementsSnapshot.newBuilder()
                        .setHttps(true)
                        .setTurbo(true)
                        .setSpeedGradeMobile(5)
                        .setTld("ru")
                        .build())
                .addAchievementsOld(Digest.AchievementsSnapshot.newBuilder()
                        .setTurbo(false)
                        .setPopular(1)
                        .setSpeedGradeMobile(1)
                        .setTld("kz")
                        .build())
                .addAchievementsNew(Digest.AchievementsSnapshot.newBuilder()
                        .setTurbo(true)
                        .setPopular(5)
                        .setSpeedGradeMobile(5)
                        .setTld("kz")
                        .build());

        String[] tlds = new String[]{"by", "uz", "ua"};

        for (String tld : tlds) {
            builder.addAchievementsOld(Digest.AchievementsSnapshot.newBuilder()
                            .setSpeedGradeMobile(1)
                            .setTld(tld)
                            .build())
                    .addAchievementsNew(Digest.AchievementsSnapshot.newBuilder()
                            .setSpeedGradeMobile(5)
                            .setTld(tld)
                            .build());
        }

        return builder.build();
    }
    private Digest.TopQuerySamples getTopQueriesSamples() {
        return Digest.TopQuerySamples.newBuilder()
                .addPositiveQueryClicksSamples(Digest.QueryClicksSample.newBuilder()
                        .setQuery("новости дня")
                        .setClicks(Digest.IndicatorLong.newBuilder()
                                .setOldValue(4727)
                                .setNewValue(4875)
                                .setDiff(148)
                                .setDiffPercent(3.130949862)
                                .build())
                        .build())
                .addNegativeQueryClicksSamples(Digest.QueryClicksSample.newBuilder()
                        .setQuery("лента")
                        .setClicks(Digest.IndicatorLong.newBuilder()
                                .setOldValue(25990)
                                .setNewValue(24929)
                                .setDiff(-1061)
                                .setDiffPercent(-4.082339361)
                                .build())
                        .build())
                .addPositiveQueryShowsSamples(Digest.QueryShowsSample.newBuilder()
                        .setQuery("поющие фонтаны екатеринбург 2019")
                        .setShows(Digest.IndicatorLong.newBuilder()
                                .setOldValue(6)
                                .setNewValue(3715)
                                .setDiff(3709)
                                .setDiffPercent(61816.66667)
                                .build())
                        .build())
                .addNegativeQueryShowsSamples(Digest.QueryShowsSample.newBuilder()
                        .setQuery("все пассажиры рейса в москву отказались от полета на ssj 100")
                        .setShows(Digest.IndicatorLong.newBuilder()
                                .setOldValue(16563)
                                .setNewValue(163)
                                .setDiff(-16400)
                                .setDiffPercent(-99.01587877)
                                .build())
                        .build())
                .addPositiveQueryPositionSamples(Digest.QueryPositionSample.newBuilder()
                        .setQuery("новости о самолете сегодня")
                        .setPosition(Digest.IndicatorDouble.newBuilder()
                                .setOldValue(42)
                                .setNewValue(14)
                                .setDiff(-28)
                                .setDiffPercent(-66.66666667)
                                .build())
                        .build())
                .addNegativeQueryPositionSamples(Digest.QueryPositionSample.newBuilder()
                        .setQuery("пикабу")
                        .setPosition(Digest.IndicatorDouble.newBuilder()
                                .setOldValue(7.475409836)
                                .setNewValue(33.08064516)
                                .setDiff(25.60523533)
                                .setDiffPercent(342.5261743)
                                .build())
                        .build())
                .build();
    }

    private Digest.RecommendedUrls getRecommendedUrls() {
        return Digest.RecommendedUrls.newBuilder()
                .addRecommendedUrls(Digest.RecommendedUrlState.newBuilder()
                        .setClicks(87)
                        .setPath("/%D1%81%D0%B8%D0%B3%D0%B0%D1%80%D0%B5%D1%82%D1%8B-%D0%BC%D1%83%D1%82%D0%B0%D0%BA%D0%B8/")
                        .setShows(17494)
                        .build())
                .addRecommendedUrls(Digest.RecommendedUrlState.newBuilder()
                        .setClicks(50)
                        .setPath("/url/textPage/")
                        .setShows(15000)
                        .build())
                .build();
    }

    private Digest.CheckList getChecklistStatus() {
        return Digest.CheckList.newBuilder()
                .setOldStatus(Digest.CheckListStatus.newBuilder()
                        .addProblems(34)
                        .addProblems(37)
                        .addProblems(40)
                        .addProblems(31)
                        .build()
                )
                .setNewStatus(Digest.CheckListStatus.newBuilder()
                        .addProblems(40)
                        .addProblems(37)
                        .addProblems(22)
                        .addProblems(31)
                        .addProblems(34)
                        .addProblems(49)
                        .build()
                )
                .build();
    }

    private Digest.AllQueriesIndicators getAllQueries() {
        return Digest.AllQueriesIndicators.newBuilder()
                .setPosition(Digest.IndicatorDouble.newBuilder()
                        .setOldValue(11.0)
                        .setNewValue(10.0)
                        .setDiff(-1.0)
                        .setDiffPercent(-9.09)
                        .build()
                )
                .setClicks(Digest.IndicatorLong.newBuilder()
                        .setOldValue(234838)
                        .setNewValue(217049)
                        .setDiff(-17789)
                        .setDiffPercent(-7.575009155)
                        .build()
                )
                .setShows(Digest.IndicatorLong.newBuilder()
                        .setOldValue(4678702)
                        .setNewValue(3729094)
                        .setDiff(-949608)
                        .setDiffPercent(-20.29639845)
                        .build()
                )
                .addOldClicksByPeriod(Digest.ClicksByPeriod.newBuilder().setClicks(42376).setTimestamp(1558299600).build())
                .addOldClicksByPeriod(Digest.ClicksByPeriod.newBuilder().setClicks(36013).setTimestamp(1558386000).build())
                .addOldClicksByPeriod(Digest.ClicksByPeriod.newBuilder().setClicks(37297).setTimestamp(1558472400).build())
                .addOldClicksByPeriod(Digest.ClicksByPeriod.newBuilder().setClicks(36553).setTimestamp(1558558800).build())
                .addOldClicksByPeriod(Digest.ClicksByPeriod.newBuilder().setClicks(37429).setTimestamp(1558645200).build())
                .addOldClicksByPeriod(Digest.ClicksByPeriod.newBuilder().setClicks(22267).setTimestamp(1558731600).build())
                .addOldClicksByPeriod(Digest.ClicksByPeriod.newBuilder().setClicks(22903).setTimestamp(1558818000).build())

                .addNewClicksByPeriod(Digest.ClicksByPeriod.newBuilder().setClicks(37993).setTimestamp(1558904400).build())
                .addNewClicksByPeriod(Digest.ClicksByPeriod.newBuilder().setClicks(35124).setTimestamp(1558990800).build())
                .addNewClicksByPeriod(Digest.ClicksByPeriod.newBuilder().setClicks(34645).setTimestamp(1559077200).build())
                .addNewClicksByPeriod(Digest.ClicksByPeriod.newBuilder().setClicks(35620).setTimestamp(1559163600).build())
                .addNewClicksByPeriod(Digest.ClicksByPeriod.newBuilder().setClicks(32728).setTimestamp(1559250000).build())
                .addNewClicksByPeriod(Digest.ClicksByPeriod.newBuilder().setClicks(18711).setTimestamp(1559336400).build())
                .addNewClicksByPeriod(Digest.ClicksByPeriod.newBuilder().setClicks(22228).setTimestamp(1559422800).build())
                .build();
    }

    private Digest.GroupQuerySamples getQueryGroupsSamples() {
        return Digest.GroupQuerySamples.newBuilder()
                .addPositiveQueryClicksSamples(Digest.GroupClicksSample.newBuilder()
                        .setGroupId("205d9ad0-2909-11e8-bf4e-17ea35d41379")
                        .setGroupName("Политика")
                        .setClicks(Digest.IndicatorLong.newBuilder()
                                .setOldValue(20)
                                .setNewValue(22)
                                .setDiff(2)
                                .setDiffPercent(10.0)
                                .build())
                        .build())
                .addNegativeQueryClicksSamples(Digest.GroupClicksSample.newBuilder()
                        .setGroupId("122904d0-290a-11e8-b4a5-3181b4a39c3d")
                        .setGroupName("Новости Категории")
                        .setClicks(Digest.IndicatorLong.newBuilder()
                                .setOldValue(35200)
                                .setNewValue(34243)
                                .setDiff(-957)
                                .setDiffPercent(-2.71875)
                                .build())
                        .build())
                .addPositiveQueryShowsSamples(Digest.GroupShowsSample.newBuilder()
                        .setGroupId("205d9ad0-2909-11e8-bf4e-17ea35d41379")
                        .setGroupName("Политика")
                        .setShows(Digest.IndicatorLong.newBuilder()
                                .setOldValue(925)
                                .setNewValue(1116)
                                .setDiff(191)
                                .setDiffPercent(20.64864865)
                                .build())
                        .build())
                .addNegativeQueryShowsSamples(Digest.GroupShowsSample.newBuilder()
                        .setGroupId("122904d0-290a-11e8-b4a5-3181b4a39c3d")
                        .setGroupName("Новости Категории")
                        .setShows(Digest.IndicatorLong.newBuilder()
                                .setOldValue(460621)
                                .setNewValue(417955)
                                .setDiff(-42666)
                                .setDiffPercent(-9.262712729)
                                .build())
                        .build())
                .addPositiveQueryPositionSamples(Digest.GroupPositionSample.newBuilder()
                        .setGroupId("205d9ad0-2909-11e8-bf4e-17ea35d41379")
                        .setGroupName("Политика")
                        .setPosition(Digest.IndicatorDouble.newBuilder()
                                .setOldValue(9.681081081)
                                .setNewValue(9.005376344)
                                .setDiff(-0.675704737)
                                .setDiffPercent(-6.979641337)
                                .build())
                        .build())
                .addNegativeQueryPositionSamples(Digest.GroupPositionSample.newBuilder()
                        .setGroupId("f6b87b90-2909-11e8-b79a-512154643b08")
                        .setGroupName("Новости Прибалтики")
                        .setPosition(Digest.IndicatorDouble.newBuilder()
                                .setOldValue(12.45454545)
                                .setNewValue(10.4)
                                .setDiff(-2.054545455)
                                .setDiffPercent(-16.49635036)
                                .build())
                        .build())
                .build();
    }

    @Required
    public void setDigestNotificationService(DigestNotificationService digestNotificationService) {
        this.digestNotificationService = digestNotificationService;
    }

    @Required
    public void setChartSettings(ChartSettings chartSettings) {
        this.chartSettings = chartSettings;
    }
}
