package server.logic.ws_protocol.JSON.handlers.auth;

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.handlers.auth.entyties.Net_CancelEspPairing_Request;
import server.logic.ws_protocol.JSON.handlers.auth.entyties.Net_CancelEspPairing_Response;
import server.logic.ws_protocol.JSON.utils.AuthKeyUtils;
import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory;
import server.logic.ws_protocol.WireCodes;
import shine.db.dao.EspPairingRequestsDAO;
import shine.db.entities.EspPairingRequestEntry;

public class Net_CancelEspPairing_Handler implements JsonMessageHandler {

    @Override
    public Net_Response handle(Net_Request baseReq, ConnectionContext ctx) throws Exception {
        Net_CancelEspPairing_Request req = (Net_CancelEspPairing_Request) baseReq;

        String pairingId = req.getPairingId() == null ? "" : req.getPairingId().trim();
        if (pairingId.isBlank()) {
            return NetExceptionResponseFactory.error(req, WireCodes.Status.BAD_REQUEST, "EMPTY_PAIRING_ID", "Пустой pairingId");
        }

        String requesterSessionKey = req.getRequesterSessionKey();
        if (requesterSessionKey == null || requesterSessionKey.isBlank()) {
            return NetExceptionResponseFactory.error(req, WireCodes.Status.BAD_REQUEST, "EMPTY_REQUESTER_SESSION_KEY", "Пустой requesterSessionKey");
        }
        try {
            requesterSessionKey = AuthKeyUtils.normalize(requesterSessionKey, "requesterSessionKey");
            AuthKeyUtils.parseEd25519PublicKey(requesterSessionKey, "requesterSessionKey");
        } catch (Exception e) {
            return NetExceptionResponseFactory.error(req, WireCodes.Status.BAD_REQUEST, "BAD_REQUESTER_SESSION_KEY", "Некорректный requesterSessionKey");
        }

        long now = System.currentTimeMillis();
        EspPairingRequestsDAO.getInstance().expirePending(now);
        EspPairingRequestEntry row = EspPairingRequestsDAO.getInstance().getByPairingId(pairingId);
        if (row == null) {
            return NetExceptionResponseFactory.error(req, 404, "PAIRING_NOT_FOUND", "Pairing-заявка не найдена");
        }
        if (!requesterSessionKey.equals(row.getRequesterSessionKey())) {
            return NetExceptionResponseFactory.error(req, 422, "PAIRING_OF_ANOTHER_REQUESTER", "Нельзя отменять pairing другого устройства");
        }
        if (!EspPairingSupport.STATE_CREATED.equals(row.getStatus())) {
            return NetExceptionResponseFactory.error(req, 422, "PAIRING_NOT_PENDING", "Заявка уже не находится в статусе created");
        }

        EspPairingRequestsDAO.getInstance().markCanceled(pairingId, "canceled_by_requester", now);

        Net_CancelEspPairing_Response resp = new Net_CancelEspPairing_Response();
        resp.setOp(req.getOp());
        resp.setRequestId(req.getRequestId());
        resp.setStatus(WireCodes.Status.OK);
        resp.setPairingId(pairingId);
        resp.setState(EspPairingSupport.STATE_CANCELED);
        return resp;
    }
}
