package apigen

import "git.qianqiusoft.com/qianqiusoft/light-apiengine-client/code_gen/utils"

/*

type XmlController struct {
	Name            string   `xml:"name,attr"`
	Desc            string   `xml:"desc,attr"`
	Dir             string   `xml:"dir,attr"`
	SkipLogin       bool     `xml:"skip_login,attr"`
	Apis            []XmlApi `xml:"api"`
	ApplicationName string   `xml:"-"`
	PackageName     string   `xml:"-"`
}

type XmlApi struct {
	Name string `xml:"name,attr"`
	Desc string `xml:"desc,attr"`
	Method string `xml:"method,attr"`
	Function string `xml:"function,attr"`//page,tree
	Table string `xml:"table,attr"`
	ParamList []XmlApiParam `xml:"param"`
	Return XmlReturn `xml:"return"`
}

type XmlApiParam struct {
	Name string `xml:"name,attr"`
	TransType string `xml:"trans-type,attr"`
	Type string `xml:"type,attr"`
	Desc string `xml:"desc,attr"`
	Ref string `xml:"ref,attr"`
	Must bool `xml:"must,attr"`
	DefaultValue string `xml:"default-value,attr"`
}
*/

const controllerTemplate = `
package gen

import (
	"git.qianqiusoft.com/qianqiusoft/light-apiengine/entitys"
	"github.com/gin-gonic/gin"
	
	"{{.app.ApplicationName}}/controllers/partial/{{.data.Dir}}"
	
	"git.qianqiusoft.com/qianqiusoft/light-apiengine/engine"
)
{{$dataName := CamelizeStr .data.Name true}}
// {{$dataName}}Controller operations for {{$dataName}}
type {{$dataName}}Controller struct {
	apiengine *engine.ApiEngine
}

func New{{$dataName}}Controller(e *engine.ApiEngine) *{{$dataName}}Controller {
	controller := &{{$dataName}}Controller{e}
	return controller
}


{{$parentName := .data.Name}}
{{range .data.Apis}}
// {{CamelizeStr .Name true}}
// @Title {{CamelizeStr .Name true}}
// @Description {{.Desc}}
// @Url {{$parentName}}/{{.Name}}
{{range .ParamList -}}
// @Param	{{.Name}}    {{.Type}}  {{.Must}}  "{{.Desc}}"
{{end -}}
// @Success 200 {object} sysReturn
// @Failure 403 :id is empty
// @router /{{.Name}}  [{{.Method}}]
func (c *{{$dataName}}Controller) {{CamelizeStr .Name true}}(ctx *gin.Context) {
	//
	db:=c.apiengine.BusinessOrmEngine[ctx.GetString("domain")]
	partial.{{$dataName}}_{{CamelizeStr .Name true}}(&entitys.CtrlContext{c.apiengine, ctx, db, c.apiengine.PlatformOrmEngine})
}
{{end}}
`

func GenController(templateData interface{}, params map[string]interface{}) ([]byte, error) {
	return utils.GenTemplate(controllerTemplate, templateData, params)
}

func GenPartial(templateData interface{}, params map[string]interface{}) ([]byte, error) {
	return utils.GenTemplate(partialTemplate, templateData, params)
}

const partialTemplate = `
package partial


import (
	"git.qianqiusoft.com/qianqiusoft/light-apiengine/entitys"
	sysmodel "git.qianqiusoft.com/qianqiusoft/light-apiengine/models"
    sysutils "git.qianqiusoft.com/qianqiusoft/light-apiengine/utils"
	"{{.app.ApplicationName}}/models"
	//__import_packages__
)

{{$parentName := .data.Name}}
{{$dataName := CamelizeStr .data.Name true}}
{{range .data.Apis}}
// _{{CamelizeStr .Name true}}
// @Title _{{CamelizeStr .Name true}}
// @Description {{.Desc}}
// @Url {{$parentName}}/{{.Name}}
{{range $i, $v := .ParamList -}}
// @Param	{{ParamName $i $v}}    {{if ne $v.Type ""}}{{$v.Type}}{{else}}{{if Contains $v.Ref "$"}}models.{{CamelizeStr (TrimPrefix (TrimSuffix $v.Ref " array") "$") true}}{{end}}{{end}}  {{$v.Must}}  "{{$v.Desc}}"
{{end -}}
// @Success 200 {object} Account
// @Failure 403 :id is empty
func {{$dataName}}_{{CamelizeStr .Name true}}(c *entitys.CtrlContext) {
{{if eq .Function "add"}}
	var bean models.{{$dataName}}
	if err := c.Ctx.ShouldBindJSON(&bean); err != nil {
		c.Ctx.JSON(200, sysmodel.SysReturn{500, err.Error(), nil})
		return
	}

	userId := c.Ctx.GetString("user_id")

	bean.CreateBy = userId
	bean.CreateTime = sysmodel.NowLocal()
	bean.LastUpdateBy = userId
	bean.LastUpdateTime = sysmodel.NowLocal()
	
	bean.DelFlag = 0

	_, err := c.Db.Insert(&bean)
	if err == nil {
		c.Ctx.JSON(200, sysmodel.SysReturn{200, "", bean.Id})
	} else {
		c.Ctx.JSON(200, sysmodel.SysReturn{500, err.Error(), nil})
	}
{{else if eq .Function "update"}}
	var bean models.{{$dataName}}
	if err := c.Ctx.ShouldBindJSON(&bean); err != nil {
		c.Ctx.JSON(200, sysmodel.SysReturn{500, err.Error(), nil})
		return
	}

	userId := c.Ctx.GetString("user_id")

	bean.LastUpdateBy = userId
	bean.LastUpdateTime = sysmodel.NowLocal()

	_, err := c.Db.ID(bean.Id).Update(&bean)
	if err != nil {
		c.Ctx.JSON(200, sysmodel.SysReturn{500, err.Error(), nil})
		return
	}

	c.Ctx.JSON(200, sysmodel.SysReturn{200, "", bean.Id})
{{else if eq .Function "delete"}}
	var paramObj0 []models.Id 
	c.Ctx.BindJSON(&paramObj0)

	ret := __none_func_{{$parentName}}__(paramObj0)
	if ret {
		c.Ctx.JSON(200, sysmodel.SysReturn{200, "", nil})
	}else{
		c.Ctx.JSON(200, sysmodel.SysReturn{500, err.Error(), nil})
	}
{{else if eq .Function "page"}}
	// 需要引用apiengine v1.1.8版本
	params := sysutils.GetPageParams(c, []sysutils.PageParam{
		{"page", "1"},
		{"rows", "10"},
	})
	// 根据业务需求对params进行处理

	if sysutils.CheckExport(c){
		// 进入导出模式，需要引用apiengine v1.1.8版本
		// 前端需要配合ExportButton插件
		exporter := sysutils.NewExcelExporterExt(c, params, "{{$parentName}}", "page")
		exporter.ExportExt()
	}else{
		// 查询模式
		result, err := sysutils.PageSearch(c.Db,"{{$parentName}}","{{.Name}}", "{{$parentName}}", params)
		if err == nil {
			c.Ctx.JSON(200, sysmodel.SysReturn{200, "", result})
		} else {
			c.Ctx.JSON(200, sysmodel.SysReturn{500, err.Error(), nil})
		}
	}
{{else if eq .Function "tree"}}
	paramMap_i_t := map[string]interface{}{"sort": "name"}
	result, err := sysutils.TreeSearch(c.Db, "{{$parentName}}","{{.Name}}", "{{$parentName}}", paramMap_i_t)
	
	if err == nil {
		c.Ctx.JSON(200, sysmodel.SysReturn{200, "", result})
	} else {
		c.Ctx.JSON(200, sysmodel.SysReturn{500, err.Error(), nil})
	}
{{else}}
{{- range $i, $v := .ParamList}}
{{- if Contains $v.Type "[]"}}
	var {{ParamName $i $v}} {{$v.Type}} 
	c.Ctx.BindJSON(&{{ParamName $i $v}})
{{- else if Contains $v.Ref "$"}}
	{{$refName := TrimPrefix $v.Ref "$" -}}
	{{if Contains $v.Ref " array" -}}
	var {{ParamName $i $v}} []models.{{CamelizeStr (TrimSuffix $refName " array") true}} 
	{{- else -}}
	var {{ParamName $i $v}} models.{{CamelizeStr $refName true}} 
	{{- end}}
	c.Ctx.BindJSON(&{{ParamName $i $v}})
{{else}}
	{{$v.Name}} := c.Ctx.Query("{{$v.Name}}")
{{- end}}
{{- end}}

	ret := __none_func_{{$parentName}}__({{AllParams .ParamList}})
	if ret {
		c.Ctx.JSON(200, sysmodel.SysReturn{200, "", nil})
	}else{
		c.Ctx.JSON(200, sysmodel.SysReturn{500, "", nil})
	}
{{end -}}
}
{{end}}

func __none_func_{{$parentName}}__(params ... interface{}) bool{
	return true
}

`
