package controllers

import (
	"encoding/json"
	"fmt"
	"oppmg/common/log"
	"oppmg/protocol"
	"oppmg/utils/exceltool"
	"strconv"

	serveauth "oppmg/services/auth"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/context"
	"github.com/astaxie/beego/validation"
)

//BaseController 基础
type BaseController struct {
	beego.Controller
}

//Prepare 实现beego.ControllerInterface 的接口
func (this *BaseController) Prepare() {
	this.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Origin", "*")
	this.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Headers", "*")
	if this.Ctx.Input.Method() == "OPTIONS" {
		this.Ctx.ResponseWriter.WriteHeader(204)
		this.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
		this.Ctx.WriteString("")
		return
	}

	p := fmt.Sprint(this.Ctx.Input.GetData("RouterPattern"))
	userid := this.GetUserId()
	companyid := this.GetCompanyId()
	ok := serveauth.ValidUserPermission(p, userid, companyid)
	if !ok {
		msg := protocol.NewMessage("10080")
		this.ResposeJson(msg)
		return
	}
	//权限校验
	return
}

func (this *BaseController) GetAppHead() (appHead protocol.BaseHeader) {
	appHead.AccessToken = this.Ctx.Input.Header(protocol.HeaderAccessToken)
	return

}

//Finish 实现beego.ControllerInterface 的接口
func (this *BaseController) Finish() {
	strByte, _ := json.Marshal(this.Data["json"])
	length := len(strByte)
	if length > 1000 {
		log.Info(fmt.Sprintf("<====Send to client:  RspBodyData: %s......", string(strByte[:1000])))
	} else {
		log.Info(fmt.Sprintf("<====Send to client: RspBodyData: %s", string(strByte)))
	}

}

func (this *BaseController) ResposeJson(msg *protocol.ResponseMessage) {
	this.Data["json"] = msg
	this.ServeJSON()
}

func (this *BaseController) GetCompanyId() int64 {
	v := this.Ctx.Input.GetData(protocol.HeaderCompanyid)
	companyid, _ := strconv.ParseInt(fmt.Sprint(v), 10, 64)

	if beego.BConfig.RunMode != "prod" && companyid == 0 {
		companyid, _ = strconv.ParseInt(this.Ctx.Input.Header("x-mmm-cid"), 10, 64)
	}
	return companyid
}

func (this *BaseController) GetUserId() int64 {
	v := this.Ctx.Input.GetData(protocol.HeaderUserid)
	userid, _ := strconv.ParseInt(fmt.Sprint(v), 10, 64)

	if beego.BConfig.RunMode != "prod" && userid == 0 {
		userid, _ = strconv.ParseInt(this.Ctx.Input.Header("x-mmm-uid"), 10, 64)
	}
	return userid
}

//Valid  valid struct
func (this *BaseController) Valid(obj interface{}) (result bool, msg *protocol.ResponseMessage) {
	/*校验*/
	var err error
	valid := validation.Validation{}
	result, err = valid.Valid(obj)
	if err != nil {
		log.Error("参数校验失败:%s", err)
		msg = protocol.BadRequestParam("1")
		return
	}
	if !result {
		log.Error("校验结果:%v", result)
		msg = protocol.BadRequestParam("1")
		return
	}

	return
}

func (this *BaseController) ResponseExcelByFile(ctx *context.Context, excelMaker *exceltool.ExcelMaker) error {
	fname := excelMaker.GetFileName()
	ctx.Output.Header("Content-Disposition", "attachment; filename="+fname)
	ctx.Output.Header("Content-Description", "File Transfer")
	ctx.Output.Header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
	ctx.Output.Header("Content-Transfer-Encoding", "binary")
	ctx.Output.Header("Expires", "0")
	ctx.Output.Header("Cache-Control", "must-revalidate")
	ctx.Output.Header("Pragma", "public")
	//跳过保存文件,直接写入ctx.ResponseWriter
	excelMaker.Xlsx.Write(ctx.ResponseWriter)
	return nil
}