package gc

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"strings"

	apiresource "github.com/pingcap/test-infra/common/model/resource"
	"github.com/pingcap/test-infra/services/rms/service/provider"
)

var _ provider.NotifierInterface = DefaultNotifier{}

type DefaultNotifier struct{}

func (d DefaultNotifier) Notify(_ context.Context, action apiresource.GcNotificationAction, content string) error {
	client := &http.Client{}
	data := []byte(fmt.Sprintf(`
{
  "msg_type": "interactive",
  "card": {
    "header": {
      "template": "turquoise",
      "title": {
        "content": "test-infra 运行通知",
        "tag": "plain_text"
      }
    },
    "elements": [
      {
        "tag": "div",
        "text": {
          "content": "%s",
          "tag": "lark_md"
        }
      }
    ]
  }
}
`, escapeTextInDoubleQuote(content)))
	req, _ := http.NewRequest(http.MethodPost, action.Feishu, bytes.NewReader(data))
	req.Header.Set("Content-Type", "application/json")
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	type Resp struct {
		Msg  string `json:"msg"`
		Code int    `json:"code"`
	}
	r := new(Resp)
	data, err = io.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	if err := json.Unmarshal(data, r); err != nil {
		return err
	}
	if r.Code != 0 {
		return fmt.Errorf(r.Msg)
	}
	return nil
}

func NewDefaultNotifier() *DefaultNotifier {
	return &DefaultNotifier{}
}

func escapeTextInDoubleQuote(content string) (escapedContent string) {
	escapedContent = strings.ReplaceAll(content, `"`, `\"`)
	escapedContent = strings.ReplaceAll(escapedContent, "\n", "\\n")
	escapedContent = strings.ReplaceAll(escapedContent, "\r", "\\r")
	escapedContent = strings.ReplaceAll(escapedContent, "\t", "\\t")
	return
}
