package common

import (
	"dbweb/core"
	"dbweb/lib/safe"
	"encoding/json"
	"sort"

	"github.com/linlexing/dbx/ddb"

	"dbweb/modules/common/recordview"

	"github.com/linlexing/dbx/scan"
	"github.com/linlexing/dbx/schema"
)

const (
	modelElementViewName = "ELEVIEW"
)

type modelElementView struct {
	EleName   string `dbx:"STR(50) PRIMARY KEY"`
	Pub       int64  `dbx:"INT PRIMARY KEY"`
	Owner     string `dbx:"STR(50) PRIMARY KEY"`
	Name      string `dbx:"STR(50) PRIMARY KEY"`
	Conts     string `dbx:"STR"`
	PlainText string
	DspCols   string
}
type ModelRecordViewElement struct {
	core.ModelElementNoParam `yaml:",inline"`
	Params                   recordview.RecordViewParam `dbx:"STR"`
}

type elementController struct{}
type elementParamRender interface {
	ElementParamRender(p *core.BillGetHandleArgs)
}
type elementAjaxProcess interface {
	ElementAjaxProcess(p *core.BillGetHandleArgs)
}

func renderBill(p *core.BillGetHandleArgs, ctrl *core.Controller) {
	tmpBP := core.BillParam{}

	if bys := safe.Bytea(p.Record.Main["PARAMS"]); bys != nil {
		if err := json.Unmarshal(bys, &tmpBP); err != nil {
			core.LOG.Panic(err)
		}
	}
	if len(ctrl.ModelName) > 0 {
		tab := core.LoadModel(ctrl.ModelName).Bill().Main
		tmpBP.FixFieldSettings(tab.Columns)
	}
	p.More["JSONParams"] = tmpBP

}
func (e *elementController) Get(p *core.BillGetHandleArgs) {
	if dest := p.Req.URL.Query().Get("dest"); dest != "" {
		if ctrl := core.FindController(dest); ctrl != nil {
			if prcs, ok := ctrl.AppController.(elementAjaxProcess); ok {
				prcs.ElementAjaxProcess(p)
				return
			}
		}
	}
	list, err := ddb.ScanStrings(p.DB, "select category from element group by category order by category")
	if err != nil {
		core.LOG.Panic(err)
	}
	p.FieldMore("CATEGORY")["Options"] = list
	r := core.ControllerNames()
	sort.Strings(r)
	p.FieldMore("CONTROLLER")["Options"] = r
	p.FieldMore("OWNER")["Options"] = []map[string]interface{}{
		map[string]interface{}{
			"Text":  "部门",
			"Value": "0",
		},
		map[string]interface{}{
			"Text":  "用户",
			"Value": "1",
		},
	}
	var ctrlSettingTmpl string
	var ctrlName string
	var ctrl *core.Controller
	if ctrlName = safe.String(p.Record.Main["CONTROLLER"]); len(ctrlName) == 0 {
		goto lrender
	}
	if ctrl = core.FindController(ctrlName); ctrl == nil {
		goto lrender
	}
	if ctrl.Bill {
		ctrlSettingTmpl = "_ctrlsetting/bill"
		renderBill(p, ctrl)
	} else {
		ctrlSettingTmpl = "_ctrlsetting/" + ctrl.Name
		if rndr, ok := ctrl.AppController.(elementParamRender); ok {
			rndr.ElementParamRender(p)
		}
	}

	if p.Render.Template().Lookup(ctrlSettingTmpl) == nil {
		ctrlSettingTmpl = ""
	}
lrender:
	p.More["CtrlSettingTmpl"] = ctrlSettingTmpl
	p.HTML()
}
func (e *elementController) Post(p *core.BillPostHandleArgs) {
	eleName := p.NewRecord.Main["NAME"].(string)
	if p.Param.Operate == core.BillOperateEdit &&
		safe.String(p.OldRecord.Main["NAME"]) != safe.String(p.NewRecord.Main["NAME"]) {
		if err := ChangeElementEleView(p.Bill.DB(), safe.String(p.OldRecord.Main["NAME"]),
			safe.String(p.NewRecord.Main["NAME"])); err != nil {
			p.Error(err)
			return
		}
		if err := ChangeElementRole(p.Bill.DB(), safe.String(p.OldRecord.Main["NAME"]),
			safe.String(p.NewRecord.Main["NAME"])); err != nil {
			p.Error(err)
			return
		}
	}
	p.Process()
	//删除缓冲区内的记录
	core.RemoveElementFromCache(eleName)
}
func (e *elementController) Delete(p *core.BillDeleteHandleArgs) {
	eleName := p.OldRecord.Main["NAME"].(string)
	if err := RemoveElementEleView(p.Bill.DB(), eleName); err != nil {
		p.Error(err)
		return
	}
	if err := RemoveElementRole(p.Bill.DB(), eleName); err != nil {
		p.Error(err)
		return
	}
	p.Remove()
	//删除缓冲区内的记录
	core.RemoveElementFromCache(eleName)
}

func (e *elementController) OnControllerInit(db ddb.TxDB) error {
	return core.LoadModel(core.ModelElementName).Set(
		ModelRecordViewElement{
			ModelElementNoParam: core.ModelElementNoParam{
				Name:       "elemng",
				Label:      "10.菜单项管理",
				Category:   "10.制度管理/10.核心模块",
				Controller: "recordview",
				Pub:        0,
				Owner:      0,
				UserName:   "sys",
				Dept:       "r",
			},
			Params: recordview.RecordViewParam{
				TableName: "ELEMENT",
				Sql: `select
	a.name   as 名称,
	a.label  as 标签,
	a.dept   as 部门代码,
	d.name   as 部门名称,
	a.category   as 类别,
	a.controller as 模块,
	a.pub        as 公共,
	(select count(*) from roleele where roleele.elename=a.name) as 角色使用次数
from element a left join dept d on a.dept=d.code
where a.owner=0 and a.dept = {{P .User.Dept.Code}}`,
				ManualPage:  false,
				UniqueField: []string{"名称"},
				Processes: []*recordview.RecordViewProcess{
					&recordview.RecordViewProcess{
						Name:        "修改",
						ElementName: "editele",
						BindRecord:  true,
					},
					&recordview.RecordViewProcess{
						Name:        "删除",
						ElementName: "deleteele",
						BindRecord:  true,
					},
					&recordview.RecordViewProcess{
						Name:        "新增",
						ElementName: "addele",
					},
					&recordview.RecordViewProcess{
						Name:        "成批替换",
						ElementName: "eleupdate",
						WithSql:     true,
					},
					&recordview.RecordViewProcess{
						Name:        "导出数据",
						ElementName: "export",
						WithSql:     true,
					},
					&recordview.RecordViewProcess{
						Name:        "汇总",
						ElementName: "total",
						WithSql:     true,
					},
					&recordview.RecordViewProcess{
						Name:        "连续操作",
						ElementName: "SequenceOperate",
						WithSql:     true,
					},
				},
				AllColumns: []*scan.ColumnType{
					&scan.ColumnType{
						Name: "名称",
						Type: schema.TypeString,
					},
					&scan.ColumnType{
						Name: "标签",
						Type: schema.TypeString,
					},
					&scan.ColumnType{
						Name: "部门代码",
						Type: schema.TypeString,
					},
					&scan.ColumnType{
						Name: "部门名称",
						Type: schema.TypeString,
					},
					&scan.ColumnType{
						Name: "类别",
						Type: schema.TypeString,
					},
					&scan.ColumnType{
						Name: "模块",
						Type: schema.TypeString,
					},
					&scan.ColumnType{
						Name: "公共",
						Type: schema.TypeInt,
					},
					&scan.ColumnType{
						Name: "角色使用次数",
						Type: schema.TypeInt,
					},
				},
			},
		})
}
func init() {
	core.RegisterModel(modelElementView{}, 1, false, modelElementViewName)
	core.RegisterBill("element", new(elementController), core.ModelElementName)
	core.RegisterInstitutionModel(core.DeptRoot,modelElementViewName,
		"pub=1 and owner in ({{P .User.ToRootDeptCodesAndSelf}})", "", "")
}
