package ru.yandex.webmaster3.worker.dashboard.notifications;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import lombok.Value;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.checklist.data.SiteProblemTypeEnum;
import ru.yandex.webmaster3.core.http.Action;
import ru.yandex.webmaster3.core.http.ActionRequest;
import ru.yandex.webmaster3.core.http.ActionResponse;
import ru.yandex.webmaster3.core.http.ReadAction;
import ru.yandex.webmaster3.storage.host.CommonDataState;
import ru.yandex.webmaster3.storage.host.CommonDataType;
import ru.yandex.webmaster3.storage.settings.dao.CommonDataStateYDao;
import ru.yandex.webmaster3.storage.user.message.MessageTypeEnum;

@ReadAction
@Component("/blocked/notifications/list")
public class GetBlockedNotificationsAction extends Action<GetBlockedNotificationsAction.Request, GetBlockedNotificationsAction.Response> {

    @Autowired
    private CommonDataStateYDao commonDataStateYDao;

    @Override
    public Response process(Request request) throws WebmasterException {

        final List<MessageInfo> checklistChangesProblems = Arrays.stream(SiteProblemTypeEnum.values()).map(x ->
                new MessageInfo(MessageTypeEnum.CHECKLIST_CHANGES, x.toString(), false)).collect(Collectors.toList());

        Set<MessageInfo> messageTypes = Arrays.stream(MessageTypeEnum.values()).map(
                x -> new MessageInfo(x, "", false)
        ).collect(Collectors.toSet());
        messageTypes.addAll(checklistChangesProblems);


        final CommonDataState value = commonDataStateYDao.getValue(CommonDataType.BLOCKED_MESSAGE_TYPES);
        if (value == null) {
            return new Response(new ArrayList<>(messageTypes));
        }
        if (!value.getValue().isBlank()) {
            final String[] split = value.getValue().split(";");
            for (var t : split) {
                final String[] strs = t.split(",", 2);
                final MessageTypeEnum type = MessageTypeEnum.valueOf(strs[0]);
                if (strs.length > 1) {
                    Arrays.stream(strs[1].split(",")).forEach(problem -> {

                        final MessageInfo msg = new MessageInfo(type, problem, true);
                        messageTypes.remove(msg);
                        messageTypes.add(msg);
                    });
                } else {
                    final MessageInfo msg = new MessageInfo(type, "", true);
                    messageTypes.remove(msg);
                    messageTypes.add(msg);
                }
            }
        }
        final List<MessageInfo> infos = new ArrayList<>(messageTypes);
        infos.sort(Comparator.comparing(MessageInfo::isEnabled).reversed()
                .thenComparing(MessageInfo::getProblem)
                .thenComparing(MessageInfo::getType, Comparator.comparing(Enum::name)));
        return new Response(infos);
    }

    public static class Request implements ActionRequest {
    }

    @Value
    public static class Response implements ActionResponse.NormalResponse {
        private List<MessageInfo> messageInfos;
    }
}
