package base

import (
	"encoding/json"
	"errors"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
	"nginx-ui/server/middleware"
	"nginx-ui/server/models"
	"strconv"
)

type Controller struct {
	beego.Controller
	jsonData *models.RespData
	// Json real data
	respData map[string]any
}

func (c *Controller) Json() {
	c.checkJsonData()
	if c.respData != nil {
		c.jsonData.Data = c.respData
	}
	c.Data["json"] = c.jsonData
	c.ServeJSON()
}

func (c *Controller) PostJson(json interface{}) {
	c.Data["json"] = json
	c.ServeJSON()
}

func (c *Controller) ErrorJson(error error) {
	c.SetCode(-1).SetMsg(error.Error()).Json()
}

func (c *Controller) checkJsonData() *Controller {
	data := c.jsonData
	if data == nil {
		data = &models.RespData{
			Code: 0,
			Msg:  "success",
			Data: nil,
		}
		c.jsonData = data
	}
	return c
}

func (c *Controller) SetData(v interface{}) *Controller {
	c.checkJsonData()
	c.jsonData.Data = v
	return c
}

func (c *Controller) AddRespData(k string, v interface{}) *Controller {
	c.checkJsonData()
	if c.respData == nil {
		c.respData = map[string]any{}
	}
	c.respData[k] = v
	return c
}

func (c *Controller) SetCode(code int) *Controller {
	c.checkJsonData()
	c.jsonData.Code = code
	return c
}
func (c *Controller) SetMsg(msg string) *Controller {
	c.checkJsonData()
	c.jsonData.Msg = msg
	return c
}

func (c *Controller) GetParam(k string) string {
	return c.Ctx.Input.Param(k)
}
func (c *Controller) GetIntParam(k string) (int, error) {
	idStr := c.Ctx.Input.Param(k)
	id, err := strconv.Atoi(idStr)
	logs.Info("id", id)
	if err != nil {
		return 0, err
	}
	return id, nil
}

func (c *Controller) GetQuery(k string) string {
	return c.Ctx.Input.Query(k)
}
func (c *Controller) GetIntQuery(k string) (int, error) {
	idStr := c.Ctx.Input.Query(k)
	id, err := strconv.Atoi(idStr)
	logs.Info("id", id)
	if err != nil {
		return 0, err
	}
	return id, nil
}

func (c *Controller) GetUser(required bool) *models.User {
	data := c.GetSession("user")
	if data == nil && required {
		middleware.WriteForbidden(c.Ctx.ResponseWriter)
		return nil
	}
	if data == nil {
		return nil
	}
	user := data.(models.User)
	return &user
}

func (c *Controller) RequiredUser() *models.User {
	return c.GetUser(true)
}

// ReadBody data 非指针
func (c *Controller) ReadBody(data any) bool {
	err := json.Unmarshal(c.Ctx.Input.RequestBody, data)
	if err != nil {
		logs.Error(err, string(c.Ctx.Input.RequestBody))
		c.ErrorJson(errors.New("数据解析异常!"))
		return false
	}
	return true
}

func (c *Controller) Forbidden() {
	c.SetCode(403).SetMsg("您没有权限操作该实例!").Json()
}