package shared

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"strings"
)

type RPCRequest struct {
	JSONRPC string         `json:"jsonrpc,omitempty"`
	Type    string         `json:"type,omitempty"`
	ID      any            `json:"id,omitempty"`
	Method  string         `json:"method,omitempty"`
	Params  map[string]any `json:"params,omitempty"`
}

type RPCError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    any    `json:"data,omitempty"`
}

type ToolCallParams struct {
	Name      string         `json:"name"`
	Arguments map[string]any `json:"arguments"`
}

func DecodeRPCRequest(payload []byte) (RPCRequest, error) {
	var request RPCRequest
	if err := json.Unmarshal(payload, &request); err != nil {
		return RPCRequest{}, fmt.Errorf("invalid json: %w", err)
	}
	if strings.TrimSpace(request.Method) == "" {
		return RPCRequest{}, errors.New("missing method")
	}
	if request.Params == nil {
		request.Params = map[string]any{}
	}
	return request, nil
}

func WriteSSE(w http.ResponseWriter, payload map[string]any) error {
	encoded, _ := json.Marshal(payload)
	_, err := fmt.Fprintf(w, "data: %s\n\n", encoded)
	return err
}

func ResultEnvelope(id any, result map[string]any) map[string]any {
	return map[string]any{
		"jsonrpc": "2.0",
		"id":      id,
		"result":  result,
		// Backward compatibility with legacy GatewayRuntime
		"type":    "res",
		"ok":      true,
		"payload": result,
		"seq":     0,
	}
}

func ErrorEnvelope(id any, code int, message string, data ...any) map[string]any {
	errPayload := map[string]any{
		"code":    code,
		"message": message,
	}
	if len(data) > 0 && data[0] != nil {
		errPayload["data"] = data[0]
	}
	return map[string]any{
		"jsonrpc": "2.0",
		"id":      id,
		"error":   errPayload,
		// Backward compatibility with legacy GatewayRuntime
		"type":    "res",
		"ok":      false,
		"payload": nil,
		"seq":     0,
	}
}

func NotificationEnvelope(method string, params map[string]any) map[string]any {
	return map[string]any{
		"jsonrpc": "2.0",
		"method":  method,
		"params":  params,
		// Backward compatibility with legacy GatewayRuntime
		"type":    "event",
		"event":   method,
		"payload": params,
		"seq":     0,
	}
}
