package controllers

import (
	"encoding/json"
	"net/http"
	"wechat-conf/service"
	"wechat-conf/utils"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/config"
)

//BaseController 基础controller
type BaseController struct {
	beego.Controller
	Context  *utils.Context
	Configer map[string]config.Configer
	RunMode  string
	serv     *service.SysServ
}

//Prepare 继承beego的
func (c *BaseController) Prepare() {
	// 读取配置文件
	c.initConfig()

	// 初始化上下文
	c.initContext()

	// 鉴权
	c.auth()

	// 路由对应的实际 Controller 初始化
	c.initController()
}

// ResponseJSON 返回JSON数据
func (c *BaseController) ResponseJSON(data interface{}) {
	c.ResponseData(data, "", http.StatusOK)
}

// ResponseError 返回错误
func (c *BaseController) ResponseError(err error, code ...int) {
	if len(code) > 0 {
		c.ResponseData(nil, err, code[0])
	}

	c.ResponseData(nil, err, http.StatusBadRequest)
}

// ResponseRaw 返回
func (c *BaseController) ResponseRaw(msg []byte, stop ...bool) {
	c.Ctx.ResponseWriter.Write(msg)

	if stop != nil && len(stop) > 0 {
		if !stop[0] {
			return
		}
	}

	c.destroyContext(true)
	c.StopRun()
}

// ResponseData 自定义的JSON返回
func (c *BaseController) ResponseData(data interface{}, msg interface{}, code int) {
	status := code

	sendMessage := ""
	switch msgVal := msg.(type) {
	case error:
		sendMessage = msgVal.Error()
	case string:
		sendMessage = msgVal
	default:
		sendMessage = ""
	}

	c.Data["json"] = JSONMessage{status, sendMessage, data}
	c.Ctx.Output.Header("Access-Control-Expose-Headers", utils.TokenHeader)

	if status == http.StatusOK {
		// 设置旧 token 过期
		// c.SetTokenExipre()

		// 生成新 token
		// c.CreateNewToken()

		//token := c.Context.Get("token").(string)
		//c.Ctx.Output.Header(utils.TokenHeader, utils.TokenSchema+" "+token)
	}

	c.destroyContext(status < http.StatusMultipleChoices)
	c.crosPolicy()
	c.ServeJSON()
	c.StopRun()
}

// initAppController 执行当前路由请求对应的 Controller 初始化
func (c *BaseController) initController() {
	if ctrl, ok := c.AppController.(ControllerInterface); ok {
		ctrl.Constructor()
	}
}

func (c *BaseController) GetBodyData() (map[string]interface{}, error) {
	var data map[string]interface{}
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &data)
	return data, err
}

func (c *BaseController) ResponseOtherEndPoint(msg map[string]interface{}) {
	c.destroyContext(true)
	c.Context.Destroy()

	c.Data["json"] = msg

	c.ServeJSON()
	c.StopRun()
}