package ws

import (
	"net/http"

	api "github.com/tech/sendico/pkg/api/http"
	r "github.com/tech/sendico/pkg/api/http/response"
	"github.com/tech/sendico/pkg/mlogger"
	"github.com/tech/sendico/server/interface/api/ws"
	"go.uber.org/zap"
	"golang.org/x/net/websocket"
)

func respond(logger mlogger.Logger, conn *websocket.Conn, messageType, apiStatus, requestID string, data any) {
	message := ws.Message{
		BaseResponse: r.BaseResponse{
			Status: apiStatus,
			Data:   data,
		},
		ID:          requestID,
		MessageType: messageType,
	}

	if err := websocket.JSON.Send(conn, message); err != nil {
		logger.Warn("Failed to send error message", zap.Error(err), zap.Any("message", message))
	}
}

func errorf(logger mlogger.Logger, messageType, requestID string, conn *websocket.Conn, resp r.ErrorResponse) {
	logger.Debug(
		"Writing error sresponse",
		zap.String("error", resp.Error),
		zap.String("details", resp.Details),
		zap.Int("code", resp.Code),
	)
	respond(logger, conn, messageType, api.MSError, requestID, &resp)
}

func Ok(logger mlogger.Logger, requestID string, data any) ws.ResponseHandler {
	res := func(messageType string, conn *websocket.Conn) {
		logger.Debug("Successfully executed request", zap.Any("sresponse", data))
		respond(logger, conn, messageType, api.MSSuccess, requestID, data)
	}
	return res
}

func Internal(logger mlogger.Logger, requestID string, err error) ws.ResponseHandler {
	res := func(messageType string, conn *websocket.Conn) {
		errorf(logger, messageType, requestID, conn,
			r.ErrorResponse{
				Error:   "internal_error",
				Details: err.Error(),
				Code:    http.StatusInternalServerError,
			})
	}
	return res
}
