package gateway

import (
	"context"

	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
	"go.uber.org/dig"
	"google.golang.org/grpc"

	gatewayv1 "github.com/tidbcloud/aisupport/packages/sdk-go/contracts/api/agent-gateway/gateway/v1"
	"github.com/tidbcloud/aisupport/packages/sdk-go/infra/rpcserver"
	"github.com/tidbcloud/aisupport/services/agent-gateway/internal/app"
	gatewayapi "github.com/tidbcloud/aisupport/services/agent-gateway/internal/services/gateway/api"
)

type HandlerParam struct {
	dig.In

	Service gatewayapi.Service
}

type Handler struct {
	gatewayv1.UnimplementedGatewayServiceServer

	service gatewayapi.Service
}

func NewHandler(param HandlerParam) app.HandlerResult {
	handler := &Handler{service: param.Service}
	return app.HandlerResult{Handler: handler, GatewayHandler: handler}
}

func (h *Handler) Name() string {
	return "GatewayService"
}

func (h *Handler) RegisterRPC(server *grpc.Server) error {
	gatewayv1.RegisterGatewayServiceServer(server, h)
	return nil
}

func (h *Handler) RegisterGateway(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
	return gatewayv1.RegisterGatewayServiceHandler(ctx, mux, conn)
}

func (h *Handler) ProcessMessage(ctx context.Context, req *gatewayv1.ProcessMessageRequest) (*gatewayv1.ProcessMessageResponse, error) {
	result, err := h.service.ProcessMessage(ctx, gatewayapi.ProcessMessageRequest{
		Context: req.GetContext(),
		Message: req.GetMessage(),
	})
	if err != nil {
		return nil, err
	}
	disposition := gatewayv1.ProcessMessageDisposition_PROCESS_MESSAGE_DISPOSITION_DUPLICATED
	if result.Created {
		disposition = gatewayv1.ProcessMessageDisposition_PROCESS_MESSAGE_DISPOSITION_ACCEPTED
	}
	return &gatewayv1.ProcessMessageResponse{Disposition: disposition, Task: result.Task}, nil
}

func (h *Handler) ProcessLarkMessage(ctx context.Context, req *gatewayv1.ProcessLarkMessageRequest) (*gatewayv1.ProcessLarkMessageResponse, error) {
	result, err := h.service.ProcessLarkMessage(ctx, gatewayapi.ProcessLarkMessageRequest{
		Context: req.GetContext(),
		Message: req.GetMessage(),
	})
	if err != nil {
		return nil, err
	}
	disposition := gatewayv1.ProcessLarkMessageDisposition_PROCESS_LARK_MESSAGE_DISPOSITION_DUPLICATED
	if result.Created {
		disposition = gatewayv1.ProcessLarkMessageDisposition_PROCESS_LARK_MESSAGE_DISPOSITION_ACCEPTED
	}
	return &gatewayv1.ProcessLarkMessageResponse{Disposition: disposition, Task: result.Task}, nil
}

var _ gatewayv1.GatewayServiceServer = (*Handler)(nil)
var _ rpcserver.RPCHandler = (*Handler)(nil)
var _ rpcserver.GatewayHandler = (*Handler)(nil)
