package tmi

import (
	"bytes"
	"encoding/json"
	"net/http"

	"context"

	"code.justin.tv/foundation/twitchclient"
)

type SendWhisperParams struct {
	SenderLogin string      `json:"sender_login"`
	TargetLogin string      `json:"target_login"`
	SenderIP    string      `json:"sender_ip"`
	Body        string      `json:"body"`
	Tags        WhisperTags `json:"tags"`
}

type WhisperTags struct {
	Badges      []WhisperBadge  `json:"badges"`
	Color       string          `json:"color"`
	DisplayName string          `json:"display_name"`
	Emotes      []EmoticonMatch `json:"emotes"`
	MessageID   int64           `json:"message_id"`
	ThreadID    string          `json:"thread_id"`
	Turbo       bool            `json:"turbo"`
	UserID      int             `json:"user_id"`
	UserType    string          `json:"user_type"`
}

type WhisperBadge struct {
	ID      string `json:"id"`
	Version string `json:"version"`
}

func (c *clientImpl) SendWhisper(ctx context.Context, params SendWhisperParams, reqOpts *twitchclient.ReqOpts) error {
	path := "/whispers/publish"
	bodyBytes, err := json.Marshal(params)
	if err != nil {
		return err
	}

	req, err := c.NewRequest("POST", path, bytes.NewReader(bodyBytes))
	if err != nil {
		return err
	}

	combinedReqOpts := twitchclient.MergeReqOpts(reqOpts, twitchclient.ReqOpts{
		StatName:       "service.clue.send_whisper",
		StatSampleRate: defaultStatSampleRate,
	})
	resp, err := c.Do(ctx, req, combinedReqOpts)
	if err != nil {
		return err
	}

	defer closeBody(resp)

	if resp.StatusCode != http.StatusOK {
		return twitchclient.HandleFailedResponse(resp)
	}
	return nil
}
