package luckygiftclient

import (
	"context"
	"time"

	luckygiftv1 "hyapp.local/api/proto/luckygift/v1"

	"google.golang.org/grpc"
)

type SendCommand struct {
	TraceRequestID string
	AppCode        string
	RequestID      string
	ExternalUserID string
	DeviceID       string
	// UserRegisteredAtMS 是外部 App 用户 owner 提供的账号创建事实；integration 层只原样透传，
	// 不用网关收包时间或该用户首次请求时间填充，否则会错误改变完整历史窗口资格。
	UserRegisteredAtMS int64
	GiftCount          int64
	UnitAmount         int64
	TotalAmount        int64
	Currency           string
	MetadataJSON       string
	PaidAtMS           int64
}

type SendResult struct {
	DrawID         string `json:"draw_id,omitempty"`
	RequestID      string `json:"request_id,omitempty"`
	AppCode        string `json:"app_code,omitempty"`
	ExternalUserID string `json:"external_user_id,omitempty"`
	GiftCount      int64  `json:"gift_count,omitempty"`
	UnitAmount     int64  `json:"unit_amount,omitempty"`
	TotalAmount    int64  `json:"total_amount,omitempty"`
	RewardAmount   int64  `json:"reward_amount,omitempty"`
	MultiplierPPM  int64  `json:"multiplier_ppm,omitempty"`
	RewardStatus   string `json:"reward_status,omitempty"`
	RuleVersion    int64  `json:"rule_version,omitempty"`
	CreatedAtMS    int64  `json:"created_at_ms,omitempty"`
}

type Client interface {
	SendLuckyGift(ctx context.Context, cmd SendCommand) (SendResult, error)
}

type GRPCClient struct {
	client luckygiftv1.LuckyGiftServiceClient
}

func NewGRPC(conn grpc.ClientConnInterface) *GRPCClient {
	return &GRPCClient{client: luckygiftv1.NewLuckyGiftServiceClient(conn)}
}

func (c *GRPCClient) SendLuckyGift(ctx context.Context, cmd SendCommand) (SendResult, error) {
	resp, err := c.client.ExecuteExternalGiftDraw(ctx, &luckygiftv1.ExternalGiftDrawRequest{
		Meta: &luckygiftv1.RequestMeta{
			RequestId: cmd.TraceRequestID,
			Caller:    "luck-gateway",
			SentAtMs:  time.Now().UTC().UnixMilli(),
			AppCode:   cmd.AppCode,
		},
		AppCode:            cmd.AppCode,
		ExternalUserId:     cmd.ExternalUserID,
		DeviceId:           cmd.DeviceID,
		UserRegisteredAtMs: cmd.UserRegisteredAtMS,
		RequestId:          cmd.RequestID,
		GiftCount:          cmd.GiftCount,
		UnitAmount:         cmd.UnitAmount,
		TotalAmount:        cmd.TotalAmount,
		Currency:           cmd.Currency,
		PaidAtMs:           cmd.PaidAtMS,
		MetadataJson:       cmd.MetadataJSON,
	})
	if err != nil {
		return SendResult{}, err
	}
	return fromProto(resp), nil
}

func fromProto(result *luckygiftv1.ExternalGiftDrawResponse) SendResult {
	if result == nil {
		return SendResult{}
	}
	return SendResult{
		DrawID:         result.GetDrawId(),
		RequestID:      result.GetRequestId(),
		AppCode:        result.GetAppCode(),
		ExternalUserID: result.GetExternalUserId(),
		GiftCount:      result.GetGiftCount(),
		UnitAmount:     result.GetUnitAmount(),
		TotalAmount:    result.GetTotalAmount(),
		RewardAmount:   result.GetRewardAmount(),
		MultiplierPPM:  result.GetMultiplierPpm(),
		RewardStatus:   result.GetRewardStatus(),
		RuleVersion:    result.GetRuleVersion(),
		CreatedAtMS:    result.GetCreatedAtMs(),
	}
}
