package server.logic.ws_protocol.JSON.messages;

import server.logic.ws_protocol.JSON.ConnectionContext;
import server.logic.ws_protocol.JSON.entyties.Net_Request;
import server.logic.ws_protocol.JSON.entyties.Net_Response;
import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler;
import server.logic.ws_protocol.JSON.messages.entyties.Net_ReceiveIncomingMessage_Request;
import server.logic.ws_protocol.JSON.messages.entyties.Net_ReceiveIncomingMessage_Response;
import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory;
import server.logic.ws_protocol.WireCodes;
import shine.db.entities.SignedMessageV2Entry;

public class Net_ReceiveIncomingMessage_Handler implements JsonMessageHandler {
    @Override
    public Net_Response handle(Net_Request baseRequest, ConnectionContext ctx) throws Exception {
        Net_ReceiveIncomingMessage_Request req = (Net_ReceiveIncomingMessage_Request) baseRequest;
        if (isBlank(req.getIncomingBlobB64())) {
            return NetExceptionResponseFactory.error(req, WireCodes.Status.BAD_REQUEST, "BAD_FIELDS", "incomingBlobB64 обязателен");
        }

        final SignedMessageBlock incoming;
        try {
            incoming = SignedMessagesCore.parseFromB64(req.getIncomingBlobB64());
        } catch (IllegalArgumentException ex) {
            return NetExceptionResponseFactory.error(req, WireCodes.Status.BAD_REQUEST, ex.getMessage(), "Некорректный формат входящего блока");
        }
        if (!incoming.isIncomingType()) {
            return NetExceptionResponseFactory.error(req, WireCodes.Status.BAD_REQUEST, "BAD_MESSAGE_TYPE", "API принимает только входящие типы 1/3");
        }

        try {
            SignedMessagesCore.verifyUsersAndSignature(incoming);
        } catch (IllegalArgumentException ex) {
            String code = ex.getMessage();
            int status = "USER_NOT_FOUND".equals(code) ? 404 : WireCodes.Status.UNVERIFIED;
            return NetExceptionResponseFactory.error(req, status, code, "Сообщение не прошло проверку");
        }

        final SignedMessageV2Entry entry;
        try {
            entry = SignedMessagesCore.toEntry(incoming, "ReceiveIncomingMessage", null);
        } catch (IllegalArgumentException ex) {
            return NetExceptionResponseFactory.error(req, WireCodes.Status.BAD_REQUEST, ex.getMessage(), "Некорректный payload подтверждения");
        }

        boolean inserted = SignedMessagesCore.saveIfAbsent(entry);
        SignedMessagesRealtime.DeliveryCounters counters = new SignedMessagesRealtime.DeliveryCounters();
        if (inserted) {
            counters = SignedMessagesRealtime.deliverToTargetSessions(entry, null);
        }

        Net_ReceiveIncomingMessage_Response resp = new Net_ReceiveIncomingMessage_Response();
        resp.setOp(req.getOp());
        resp.setRequestId(req.getRequestId());
        resp.setStatus(WireCodes.Status.OK);
        resp.setMessageKey(entry.getMessageKey());
        resp.setBaseKey(entry.getBaseKey());
        resp.setDeliveredWsSessions(counters.wsDelivered);
        resp.setDeliveredWebPushSessions(counters.pushDelivered);
        return resp;
    }

    private boolean isBlank(String s) {
        return s == null || s.isBlank();
    }
}
