package ru.yandex.webmaster3.worker.feedback;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import ru.yandex.webmaster3.core.feedback.FeedbackType;
import ru.yandex.webmaster3.core.feedback.SendFeedbackEMailTaskData;
import ru.yandex.webmaster3.core.notification.LanguageEnum;
import ru.yandex.webmaster3.core.util.IdUtils;
import ru.yandex.webmaster3.core.worker.task.TaskResult;
import ru.yandex.webmaster3.storage.notifications.service.EmailSenderService;
import ru.yandex.webmaster3.storage.notifications.service.UserNotificationSettingsService;
import ru.yandex.webmaster3.tanker.I18nSupportEmailCommons;
import ru.yandex.webmaster3.worker.Task;

/**
 * @author: ishalaru
 * DATE: 01.07.2019
 * Сервис отправляет в саппорт письма, о том что у нас отключали фукнкции турбо.
 */
@Component("sendEmailFeedbackTask")
public class SendEmailFeedbackTask extends Task<SendFeedbackEMailTaskData> {
    private static final Logger log = LoggerFactory.getLogger(SendEmailFeedbackTask.class);
    static final int MAX_RETRY_ATTEMPT = 5;
    private static final String TURBO_SUBJECT =
            I18nSupportEmailCommons.FEEDBACK_SUBJECT.createRenderableText(LanguageEnum.DEFAULT_EMAIL_LANGUAGE).render();
    private static final String WEBMASTER_SUBJECT =
            I18nSupportEmailCommons.WEBMASTER_FEEDBACK_SUBJECT.createRenderableText(LanguageEnum.DEFAULT_EMAIL_LANGUAGE).render();

    private Map<String, Set<FeedbackType>> turboSupportEmailAddresses;
    private Map<String, Set<FeedbackType>> webmasterSupportEmailAddresses;
    private EmailSenderService emailSenderService;
    private UserNotificationSettingsService userNotificationSettingsService;

    @Autowired
    public SendEmailFeedbackTask(
            @Value("#{${webmaster3.worker.feedbacks.turbo.support.email.address}}")
                    Map<String, List<String>> turboSupportEmailAddresses,
            @Value("#{${webmaster3.worker.feedbacks.webmaster.support.email.address}}")
                    Map<String, List<String>> webmasterSupportEmailAddresses,
            EmailSenderService emailSenderService,
            UserNotificationSettingsService userNotificationSettingsService) {

        log.info("Parameters : {}", turboSupportEmailAddresses);
        this.turboSupportEmailAddresses = turboSupportEmailAddresses.entrySet().stream()
                .map(e -> Pair.of(e.getKey(), e.getValue().stream().filter(Predicate.not(String::isBlank)).map(FeedbackType::valueOf).collect(Collectors.toSet())))
                .collect(Collectors.toMap(Pair::getKey, Pair::getValue));
        this.webmasterSupportEmailAddresses = webmasterSupportEmailAddresses.entrySet().stream()
                .map(e -> Pair.of(e.getKey(), e.getValue().stream().filter(Predicate.not(String::isBlank)).map(FeedbackType::valueOf).collect(Collectors.toSet())))
                .collect(Collectors.toMap(Pair::getKey, Pair::getValue));
        this.emailSenderService = emailSenderService;
        this.userNotificationSettingsService = userNotificationSettingsService;
    }

    @Override
    public Result run(SendFeedbackEMailTaskData data) throws Exception {
        log.debug("Send feedback message: {}", data);
        String userEmail = userNotificationSettingsService.getUserEmailOrDefaultIfEmpty(data.getUserId());
        if (userEmail == null) {
            userEmail = "null; UserId = " + data.getUserId();
        }
        String body = I18nSupportEmailCommons.FEEDBACK_BODY.
                newBuilder(LanguageEnum.DEFAULT_EMAIL_LANGUAGE)
                .user_email(userEmail)
                .site(data.getHostId() == null ? "" : IdUtils.hostIdToUrl(data.getHostId()))
                .disabled_function(data.getFeedbackType().toString())
                .message(data.getMessage())
                .meta(data.getMeta() == null ? "" : data.getMeta())
                .render();
        var subject = WEBMASTER_SUBJECT;
        var emailsAddresses = webmasterSupportEmailAddresses;

        if (data.getFeedbackType().isTurbo()) {
            subject = TURBO_SUBJECT;
            emailsAddresses = turboSupportEmailAddresses;
        }

        final Collection<String> emails = filterEmailsByFeedbackType(data.getFeedbackType(), emailsAddresses);

        if (!send(emails, subject, body)) {
            log.error("Can't send email to {}, with body: {}", emailsAddresses, subject, body);
            return new Result(TaskResult.UNKNOWN);
        }
        return new Result(TaskResult.SUCCESS);
    }

    private Collection<String> filterEmailsByFeedbackType(FeedbackType feedbackType, Map<String, Set<FeedbackType>> emailAddressesWithTypes) {
        List<String> result = new ArrayList<>(emailAddressesWithTypes.size());
        for (var item : emailAddressesWithTypes.entrySet()) {
            if (item.getValue() == null || item.getValue().isEmpty() || item.getValue().contains(feedbackType)) {
                result.add(item.getKey());
            }
        }
        return result;
    }

    private boolean send(Collection<String> sendEmailAddress, String subject, String body) {
        int value = MAX_RETRY_ATTEMPT;
        while (!sendEmailAddress.isEmpty() && value > 0) {
            sendEmailAddress.removeIf(s -> emailSenderService.sendEmail(s, "", subject, body));
            value--;
        }
        return sendEmailAddress.isEmpty();

    }

    @Override
    public Class<SendFeedbackEMailTaskData> getDataClass() {
        return SendFeedbackEMailTaskData.class;
    }

}
