package models

import (
	"LAPP_LF_MOM_BACKEND/db"
	"LAPP_LF_MOM_BACKEND/utils"
	"errors"
)

/***
*CreateBy:lou
*Date:2020/5/15
*TableName:菜单表
**********/

type Menu struct {
	MenuId     int    `xorm:"not null pk comment('菜单ID') int(0)" form:"menu_id" json:"menu_id"`
	MenuName   string `xorm:"comment('菜单标题') VARCHAR(40)" form:"menu_name" json:"menu_name"`
	Title      string `xorm:"comment('菜单标题') VARCHAR(40)" form:"title" json:"title"`
	Icon       string `xorm:"comment('菜单标题') VARCHAR(40)" form:"icon" json:"icon"`
	Path       string `xorm:"comment('菜单标题') VARCHAR(128)" form:"path" json:"path"`
	Paths      string `xorm:"comment('菜单标题') VARCHAR(128)" form:"paths" json:"paths"`
	MenuType   string `xorm:"comment('菜单标题') VARCHAR(1)" form:"menu_type" json:"menu_type"`
	Action     string `xorm:"comment('菜单标题') VARCHAR(16)" form:"action" json:"action"`
	Permission string `xorm:"comment('菜单标题') VARCHAR(32)" form:"permission" json:"permission"`
	ParentId   int    `xorm:"comment('菜单ID') int(0)" form:"parent_id" json:"parent_id"`
	NoCache    string `xorm:"comment('菜单标题') VARCHAR(1)" form:"no_cache" json:"no_cache"`
	Breadcrumb string `xorm:"comment('菜单标题') VARCHAR(32)" form:"breadcrumb" json:"breadcrumb"`
	Component  string `xorm:"comment('菜单标题') VARCHAR(32)" form:"component" json:"component"`
	Sort       int    `xorm:"comment('菜单标题') int(4)" form:"sort" json:"sort"`
	Visible    string `xorm:"comment('菜单标题') VARCHAR(1)" form:"visible" json:"visible"`
	CreateBy   string `xorm:"comment('菜单标题') VARCHAR(128)" form:"create_by" json:"create_by"`
	UpdateBy   string `xorm:"comment('菜单标题') VARCHAR(128)" form:"update_by" json:"update_by"`
	IsFrame    string `xorm:"comment('菜单ID') int(0)" form:"is_frame" json:"is_frame"`
	DataScope  string `json:"dataScope" xorm:"-"`
	Params     string `json:"params" xorm:"-"`
	RoleId     int    `xorm:"-" form:"role_id" json:"role_id"`
	Children   []Menu `json:"children" xorm:"-"`
	IsSelect   bool   `json:"is_select" xorm:"-"`
}

type MenuB struct {
	MenuName   string `form:"menu_name" json:"menu_name"`
	Title      string `form:"title" json:"title"`
	Icon       string `form:"icon" json:"icon"`
	Path       string `form:"path" json:"path"`
	Paths      string `form:"paths" json:"paths"`
	MenuType   string `form:"menu_type" json:"menu_type"`
	Action     string `form:"action" json:"action"`
	Permission string `form:"permission" json:"permission"`
	ParentId   int    `form:"parent_id" json:"parent_id"`
	NoCache    string `form:"no_cache" json:"no_cache"`
	Breadcrumb string `form:"breadcrumb" json:"breadcrumb"`
	Component  string `form:"component" json:"component"`
	Sort       int    `form:"sort" json:"sort"`
	Visible    string `form:"visible" json:"visible"`
	CreateBy   string `form:"create_by" json:"create_by"`
	UpdateBy   string `form:"update_by" json:"update_by"`
	IsFrame    string `form:"is_frame" json:"is_frame"`
}
type MenuLable struct {
	Id       int         `json:"id" xorm:"-"`
	Label    string      `json:"label" xorm:"-"`
	Children []MenuLable `json:"children" xorm:"-"`
}

type Menus struct {
	MenuId     int    `json:"menu_id" xorm:"column:menu_id"`
	MenuName   string `json:"menu_name" xorm:"column:menu_name"`
	Title      string `json:"title" xorm:"column:title"`
	Icon       string `json:"icon" xorm:"column:icon"`
	Path       string `json:"path" xorm:"column:path"`
	MenuType   string `json:"menu_type" xorm:"column:menu_type"`
	Action     string `json:"action" xorm:"column:action"`
	Permission string `json:"permission" xorm:"column:permission"`
	ParentId   int    `json:"parent_id" xorm:"column:parent_id"`
	NoCache    bool   `json:"no_cache" xorm:"column:no_cache"`
	Breadcrumb string `json:"breadcrumb" xorm:"column:breadcrumb"`
	Component  string `json:"component" xorm:"column:component"`
	Sort       int    `json:"sort" xorm:"column:sort"`

	Visible  string `json:"visible" xorm:"column:visible"`
	Children []Menu `json:"children" xorm:"-"`

	CreateBy  string `json:"create_by" xorm:"column:create_by"`
	UpdateBy  string `json:"update_by" xorm:"column:update_by"`
	DataScope string `json:"dataScope" xorm:"-"`
	Params    string `json:"params" xorm:"-"`
}

func (t *Menu) TableName() string {
	return "menu"
}

type MenuRole struct {
	Menus
	IsSelect bool `json:"is_select" gorm:"-"`
}

type MS []Menu

// 清除string字段的右侧空格
func (t *Menu) Clipped() {
	utils.TrimStruct(t, *t)
}

//根据菜单id，查询菜单
func (t *Menu) GetByMenuId() (Menu Menu, err error) {
	e := db.Eloquent.Master()
	_, err = e.Table(t.TableName()).Where("menu_id = ? and visible = 0", t.MenuId).Get(&Menu)
	if err != nil {
		return
	}
	return
}

func (t *Menu) SetMenu() (m []Menu, err error) {
	menulist, err := t.GetPage()
	m = make([]Menu, 0)
	for i := 0; i < len(menulist); i++ {
		menulist[i].Clipped()
		if menulist[i].ParentId != 0 {
			continue
		}
		menusInfo := DiguiMenu(&menulist, menulist[i])

		m = append(m, menusInfo)
	}
	return
}
func DiguiMenu(menulist *[]Menu, menu Menu) Menu {
	list := *menulist

	min := make([]Menu, 0)
	for j := 0; j < len(list); j++ {
		if menu.MenuId != list[j].ParentId {
			continue
		}
		mi := Menu{}
		mi.MenuId = list[j].MenuId
		mi.MenuName = list[j].MenuName
		mi.Title = list[j].Title
		mi.Icon = list[j].Icon
		mi.Path = list[j].Path
		mi.MenuType = list[j].MenuType
		mi.Action = list[j].Action
		mi.Permission = list[j].Permission
		mi.ParentId = list[j].ParentId
		mi.NoCache = list[j].NoCache
		mi.Breadcrumb = list[j].Breadcrumb
		mi.Component = list[j].Component
		mi.Sort = list[j].Sort
		mi.Visible = list[j].Visible
		mi.Children = []Menu{}
		utils.TrimStruct(&mi, mi)
		if mi.MenuType != "F" {
			ms := DiguiMenu(menulist, mi)
			utils.TrimStruct(&ms, ms)
			min = append(min, ms)

		} else {
			min = append(min, mi)
		}

	}
	menu.Children = min
	return menu
}

func (t *Menu) SetMenuRole(rolename string) (m []Menu, err error) {

	menulist := t.GetByRoleName(rolename)
	for i := 0; i < len(menulist); i++ {
		if menulist[i].ParentId != 0 {
			continue
		}
		menusInfo := DiguiMenu(&menulist, menulist[i])
		utils.TrimStruct(&menusInfo, menusInfo)
		m = append(m, menusInfo)
	}
	return
}

func (t *Menu) GetByRoleName(rolename string) []Menu {
	menus := make([]Menu, 0)
	e := db.Eloquent.Master()
	err := e.SQL("select menu.* from menu left join role_menu on role_menu.menu_id=menu.menu_id where role_menu.role_name=? and menu.menu_type in ('M','C') and menu.visible = 0", rolename).Find(&menus)
	if err != nil {
		return nil
	}
	return menus
}
func (t *Menu) SetMenuLable() (m []MenuLable, err error) {
	menulist, err := t.Get()

	m = make([]MenuLable, 0)
	for i := 0; i < len(menulist); i++ {
		menulist[i].Clipped()
		if menulist[i].ParentId != 0 {
			continue
		}
		e := MenuLable{}
		e.Id = menulist[i].MenuId
		e.Label = menulist[i].Title
		menusInfo := DiguiMenuLable(&menulist, e)

		m = append(m, menusInfo)
	}
	return
}

func DiguiMenuLable(menulist *[]Menu, menu MenuLable) MenuLable {
	list := *menulist

	min := make([]MenuLable, 0)
	for j := 0; j < len(list); j++ {
		list[j].Clipped()
		if menu.Id != list[j].ParentId {
			continue
		}
		mi := MenuLable{}
		mi.Id = list[j].MenuId
		mi.Label = list[j].Title
		mi.Children = []MenuLable{}
		if list[j].MenuType != "F" {
			ms := DiguiMenuLable(menulist, mi)
			min = append(min, ms)
		} else {
			min = append(min, mi)
		}

	}
	menu.Children = min
	return menu
}

func (t *MenuRole) Get() (Menus []MenuRole, err error) {
	e := db.Eloquent.Master()
	table := e.Table("menu")
	if t.MenuName != "" {
		table = table.Where("menu_name = ?", t.MenuName)
	}
	if err = table.OrderBy("sort").Find(&Menus); err != nil {
		return
	}
	return
}

func (t *Menu) Get() (Menus []Menu, err error) {
	e := db.Eloquent.Master()
	table := e.Table(t.TableName()).Where("1=1").And("menu.visible = ?",0)
	if t.MenuName != "" {
		table = table.And("menu_name = ?", t.MenuName)
	}
	if t.Path != "" {
		table = table.And("path = ?", t.Path)
	}
	if t.Action != "" {
		table = table.And("action = ?", t.Action)
	}
	if t.MenuType != "" {
		table = table.And("menu_type = ?", t.MenuType)
	}

	if err = table.OrderBy("sort").Find(&Menus); err != nil {
		return
	}
	return
}

func (t *Menu) GetPage() (Menus []Menu, err error) {
	e := db.Eloquent.Master()
	table := e.Table(t.TableName()).Where("1=1").And("visible = ?", 0)
	if t.MenuName != "" {
		table = table.And("menu_name = ?", t.MenuName)
	}
	if t.Title != "" {
		table = table.And("title = ?", t.Title)
	}

	table = table.And("menu_type in ('M','C','F')")

	if err = table.OrderBy("sort").Find(&Menus); err != nil {
		return
	}
	return
}

func (t *Menu) Create() (id int, err error) {
	e := db.Eloquent.Master()
	data := MenuB{}
	data.Sort = t.Sort
	data.Visible = t.Visible
	data.Breadcrumb = t.Breadcrumb
	data.Action = t.Action
	data.NoCache = t.NoCache
	data.Component = t.Component
	data.UpdateBy = t.UpdateBy
	data.CreateBy = t.CreateBy
	data.Icon = t.Icon
	data.MenuName = t.MenuName
	data.MenuType = t.MenuType
	data.Path = t.Path
	data.Permission = t.Permission
	data.ParentId = t.ParentId
	data.Title = t.Title
	_, err = e.Table(t.TableName()).Insert(data)
	if err != nil {
		return
	}
	//err = InitPaths(t)
	//if err != nil {
	//	return
	//}
	id = t.MenuId
	return
}

func InitPaths(menu *Menu) (err error) {
	e := db.Eloquent.Master()
	parentMenu := new(Menu)
	if int(menu.ParentId) != 0 {
		e.Table("menu").Where("menu_id = ?", menu.ParentId).Get(parentMenu)
		if parentMenu.Paths == "" {
			err = errors.New("父级paths异常，请尝试对当前节点父级菜单进行更新操作！")
			return
		}
		menu.Paths = parentMenu.Paths + "/" + utils.ValueToString(menu.MenuId, "")
	} else {
		menu.Paths = "/0/" + utils.ValueToString(menu.MenuId, "")
	}
	e.Table("menu").Where("menu_id = ?", menu.MenuId).Update("paths", menu.Paths)
	return
}

func (t *Menu) Update(id int) (err error) {

	e := db.Eloquent.Master()
	var upmenu Menu
	upmenu.Permission = t.Permission
	upmenu.ParentId = t.ParentId
	upmenu.Title = t.Title
	upmenu.Paths = t.Paths
	upmenu.Path = t.Path
	upmenu.MenuType = t.MenuType
	upmenu.MenuName = t.MenuName
	upmenu.IsFrame = t.IsFrame
	upmenu.Icon = t.Icon
	upmenu.CreateBy = t.CreateBy
	upmenu.UpdateBy = t.UpdateBy
	upmenu.Component = t.Component
	upmenu.Action = t.Action
	upmenu.Breadcrumb = t.Breadcrumb
	upmenu.Visible = t.Visible
	upmenu.Sort = t.Sort
	//参数1:是要修改的数据
	columns := []string{"permission", "parent_id", "title",
		"paths", "path", "menu_type", "menu_name", "is_frame", "icon", "breadcrumb", "visible", "sort",
		"create_by", "update_by", "component", "action"}
	//参数2:是修改的数据
	if _, err = e.Table(t.TableName()).ID(id).MustCols(columns...).Update(&upmenu); err != nil {
		return
	}
	//err = InitPaths(t)
	//if err != nil {
	//	return
	//}
	return
}

func (t *Menu) Delete(id int) (success bool, err error) {
	e := db.Eloquent.Master()
	if _, err = e.Table(t.TableName()).Where("menu_id = ?", id).Delete(&Menu{}); err != nil {
		success = false
		return
	}
	success = true
	return
}
