package ru.yandex.webmaster3.viewer.http.user.settings.notification2;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;

import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.data.WebmasterUser;
import ru.yandex.webmaster3.core.http.WriteAction;
import ru.yandex.webmaster3.core.metrics.Category;
import ru.yandex.webmaster3.storage.util.ydb.exception.WebmasterYdbException;
import ru.yandex.webmaster3.storage.notifications.NotificationChannel;
import ru.yandex.webmaster3.storage.notifications.service.UserNotificationSettingsService;
import ru.yandex.webmaster3.storage.user.dao.UserNotificationHostSettingsYDao;
import ru.yandex.webmaster3.storage.user.notification.HostNotificationMode;
import ru.yandex.webmaster3.storage.user.notification.HostNotificationSetting;
import ru.yandex.webmaster3.storage.user.notification.NotificationType;
import ru.yandex.webmaster3.viewer.http.AbstractUserAction;

/**
 * Created by ifilippov5 on 01.10.18.
 */
@WriteAction
@Description(value = "Устанавливает общую настройку email уведомления, а похостовые устанавливает в дефолт")
@Category("notifications")
@AllArgsConstructor(onConstructor_ = @Autowired)
public class UpdateHostNotification2AllHostsSettingAction extends
        AbstractUserAction<UpdateHostNotification2AllHostsSettingRequest, UpdateHostNotification2AllHostsSettingResponse> {

    private static final NotificationChannel CHANNEL_EMAIL = NotificationChannel.EMAIL;

    private final UserNotificationSettingsService userNotificationSettingsService;
    private final UserNotificationHostSettingsYDao userNotificationHostSettingsYDao;

    @Override
    public UpdateHostNotification2AllHostsSettingResponse process(UpdateHostNotification2AllHostsSettingRequest request) {
        String email = userNotificationSettingsService.getUserEmail(request.getUserId());
        boolean hasEmailSetting = email != null;

        if (email == null) {
            disableAllDefaultSettings(request.getWebmasterUser(), request.getType());
            email = userNotificationSettingsService.getDefaultEmail(request.getUserId());
            userNotificationSettingsService.saveEmail(request.getUserId(), email);//установим дефолтную почту
        }

        userNotificationSettingsService.updateDefaultSettings(request.getWebmasterUser(),
                request.getType(), CHANNEL_EMAIL, request.getDefaultSettingMode());

        Map<Long, List<HostNotificationSetting>> userHostSettings = userNotificationHostSettingsYDao.listSettingsForUsers(
                Collections.singleton(request.getUserId()));
        if (userHostSettings.containsKey(request.getUserId())) {
            for (NotificationType type : NotificationType.values()) {
                if (type == request.getType() || !hasEmailSetting) {
                    hostSettingToDefault(request.getWebmasterUser(), type, userHostSettings.get(request.getUserId()));
                }
            }
        }
        return new UpdateHostNotification2AllHostsSettingResponse.NormalResponse(email);
    }

    private void disableAllDefaultSettings(WebmasterUser user, NotificationType excludedType)  {
        for (NotificationType type : NotificationType.values()) {
            if (type == excludedType) {
                continue;
            }
            userNotificationSettingsService.updateDefaultSettings(user, type, CHANNEL_EMAIL, HostNotificationMode.DISABLED);
        }
    }

    private void hostSettingToDefault(WebmasterUser user, NotificationType targetType, List<HostNotificationSetting> currentUserHostSettings)  {
        HostNotificationMode defaultMode = HostNotificationMode.DEFAULT;
        List<WebmasterHostId> hostsForUpdateMode = currentUserHostSettings.stream()
                .filter(setting -> setting.getType() == targetType && setting.getMode() != defaultMode
                        && setting.getChannel() == CHANNEL_EMAIL)
                .map(HostNotificationSetting::getHostId)
                .collect(Collectors.toList());
        if (!hostsForUpdateMode.isEmpty()) {
            userNotificationHostSettingsYDao.updateMode(user, hostsForUpdateMode, targetType, CHANNEL_EMAIL, defaultMode);
        }
    }
}
