package controller

import (
	"bytes"
	"io"

	"github.com/gin-gonic/gin"
	"github.com/tidbcloud/escalation-base/feishu_messager_v2/api"
	"github.com/tidbcloud/escalation-base/feishu_messager_v2/pkg/infra/errs"
)

func FailWithCode(c *gin.Context, err error, code api.ErrCode) {
	resp := &api.BaseResp{
		ErrCode:    code,
		ErrMessage: err.Error(),
	}

	c.AbortWithStatusJSON(code.HTTPCode(), resp)
	c.Error(err)
}

// Fail aborts the request with an error.
// If the error is an APIError, its code and message will be used.
// Otherwise, the error will be treated as an internal error.
func Fail(c *gin.Context, err error) {
	aerr := errs.APIErrorWrap(err)
	resp := &api.BaseResp{
		ErrCode:    aerr.ErrCode(),
		ErrMessage: aerr.ErrMessage(), // TODO: hide internal error message?
	}

	c.AbortWithStatusJSON(aerr.ErrCode().HTTPCode(), resp)
	c.Error(err)
}

// Success sets the errcode to 0 and returns the response.
func Success(c *gin.Context, resp any) {
	if resp == nil {
		resp = &api.BaseResp{}
	}
	api.SetBaseResp(resp, api.ErrCodeOK, "")
	c.JSON(api.ErrCodeOK.HTTPCode(), resp)
}

// FetchBody fetches the request body and puts it back to the request.
func FetchBody(c *gin.Context) ([]byte, error) {
	body, err := c.GetRawData()
	c.Request.Body.Close()
	if err != nil {
		return nil, err
	}

	c.Request.Body = io.NopCloser(bytes.NewReader(body))
	return body, nil
}
