package ru.yandex.webmaster3.worker.user;

import java.util.EnumSet;
import java.util.Set;

import lombok.AllArgsConstructor;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import ru.yandex.webmaster3.core.blackbox.service.BlackboxUsersService;
import ru.yandex.webmaster3.core.worker.task.InitializeUserTaskData;
import ru.yandex.webmaster3.core.worker.task.TaskResult;
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.InitializedUsersYDao;
import ru.yandex.webmaster3.storage.user.dao.UserNotificationChannelsYDao;
import ru.yandex.webmaster3.storage.user.dao.UserNotificationEmailYDao;
import ru.yandex.webmaster3.storage.user.notification.NotificationType;
import ru.yandex.webmaster3.storage.user.service.InitializedUsersService;
import ru.yandex.webmaster3.worker.Task;

/**
 * @author avhaliullin
 */
@AllArgsConstructor(onConstructor_ = @Autowired)
@Component
public class InitializeUserTask extends Task<InitializeUserTaskData> {

    private final InitializedUsersService initializedUsersService;
    private final BlackboxUsersService blackboxExternalYandexUsersService;
    private final UserNotificationEmailYDao userNotificationEmailYDao;
    private final UserNotificationChannelsYDao userNotificationChannelsYDao;
    private final UserNotificationSettingsService userNotificationSettingsService;

    @Override
    public Result run(InitializeUserTaskData data) throws Exception {
        initializeNotificationEmail(data.getUserId(), data.getEmailInitMode(), data.getProvidedEmail());
        initializeNotificationOptions(data.getUserId(), data.isAllowSearchBaseMessages(), data.isAllowSearchBaseEmails());
        initializedUsersService.markInitialized(data.getUserId());
        return new Result(TaskResult.SUCCESS);
    }

    private void initializeNotificationOptions(long userId, Boolean allowSearchBaseMessages,
                                               Boolean allowSearchBaseEmails)  {
        if (allowSearchBaseMessages != null && allowSearchBaseEmails != null) {
            Set<NotificationChannel> channels = EnumSet.noneOf(NotificationChannel.class);
            if (allowSearchBaseMessages) {
                channels.add(NotificationChannel.SERVICE);
                if (allowSearchBaseEmails) {
                    channels.add(NotificationChannel.EMAIL);
                }
            }
            userNotificationChannelsYDao.updateSettings(userId, NotificationType.SEARCH_BASE_UPDATE, channels);
        }
        // WMC-10910 autosubscribe new users
        Set<NotificationChannel> channels = Set.of(NotificationChannel.SERVICE, NotificationChannel.EMAIL);
        userNotificationChannelsYDao.updateSettings(userId, NotificationType.SITE_PROBLEM_POSSIBLE, channels);
        userNotificationChannelsYDao.updateSettings(userId, NotificationType.SITE_PROBLEM_RECOMMENDATION, channels);
    }

    private void initializeNotificationEmail(long userId, InitializeUserTaskData.EmailInitMode emailInitMode,
                                             String providedEmail)  {
        if (emailInitMode == InitializeUserTaskData.EmailInitMode.NONE) {
            return;
        }
        String email = userNotificationEmailYDao.getEmail(userId);
        if (email == null) {
            switch (emailInitMode) {
                case DEFAULT:
                    email = blackboxExternalYandexUsersService.getDefaultEmail(userId);
                    break;
                case PROVIDED:
                    email = providedEmail;
                    break;
                default:
                    throw new IllegalArgumentException("Unknown email init mode " + emailInitMode);
            }
            userNotificationSettingsService.saveEmail(userId, email);
        }
    }

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