package socket

import (
	"context"

	protoSocket "git.toki-labs.com/toki/proto-socket/go"

	altv1 "git.toki-labs.com/toki/alt/packages/contracts/gen/go/alt/v1"
	"git.toki-labs.com/toki/alt/services/api/internal/workerclient"
)

// apiLiveHandlers returns the API session handlers for the live trading capability surface.
// Each handler validates the request shape and forwards it to the worker through
// the injected Worker client; live execution stays worker-owned.
func apiLiveHandlers(worker workerclient.WorkerClient) []sessionHandler {
	return []sessionHandler{
		{
			requestType: protoSocket.TypeNameOf(&altv1.GetLiveBrokerCapabilitiesRequest{}),
			register: func(client *protoSocket.WsClient) {
				protoSocket.AddRequestListenerTyped[*altv1.GetLiveBrokerCapabilitiesRequest, *altv1.GetLiveBrokerCapabilitiesResponse](&client.Communicator, func(req *altv1.GetLiveBrokerCapabilitiesRequest) (*altv1.GetLiveBrokerCapabilitiesResponse, error) {
					return handleGetLiveBrokerCapabilities(worker, req)
				})
			},
		},
	}
}

func handleGetLiveBrokerCapabilities(worker workerclient.WorkerClient, req *altv1.GetLiveBrokerCapabilitiesRequest) (*altv1.GetLiveBrokerCapabilitiesResponse, error) {
	if req.GetAccountId() == "" {
		return &altv1.GetLiveBrokerCapabilitiesResponse{
			Error: &altv1.ErrorInfo{Code: backtestErrorInvalidRequest, Message: "invalid live trading request: account_id is required"},
		}, nil
	}
	if worker == nil {
		return &altv1.GetLiveBrokerCapabilitiesResponse{Error: workerUnavailable()}, nil
	}
	ctx, cancel := context.WithTimeout(context.Background(), workerRequestTimeout)
	defer cancel()
	if err := worker.Connect(ctx); err != nil {
		return &altv1.GetLiveBrokerCapabilitiesResponse{Error: workerErrorInfo(err)}, nil
	}
	res, err := worker.GetLiveBrokerCapabilities(ctx, req)
	if err != nil {
		return &altv1.GetLiveBrokerCapabilitiesResponse{Error: workerErrorInfo(err)}, nil
	}
	if res == nil {
		return &altv1.GetLiveBrokerCapabilitiesResponse{Error: internalError("worker returned no live capability response")}, nil
	}
	return res, nil
}
