package system

import (
	"context"
	"time"

	"github.com/beego/beego/v2/client/orm"
	"github.com/beego/beego/v2/core/logs"
)

type MenuInfo struct {
	Id         int
	MenuOrder  int
	MenuUid    string
	FirstMenu  string
	SecondMenu string
	Creater    string
	Status     string
	CreateTime time.Time
	UpdateTime time.Time
}

// 实现排序的三个接口函数
type MenuInfoSlice []MenuInfo

func (m MenuInfoSlice) Len() int {
	return len(m)
}

func (m MenuInfoSlice) Swap(i, j int) {
	m[i], m[j] = m[j], m[i]
}

func (m MenuInfoSlice) Less(i, j int) bool {
	return m[i].MenuOrder < m[j].MenuOrder //从小到大排序
}

const MENUINFO = "menu_info"

func InsertMenu(ctx context.Context, menuInfo MenuInfo) bool {
	o := orm.NewOrm()
	_, err := o.InsertWithCtx(ctx, &menuInfo)
	if err != nil {
		logs.Error("insert new menu info fail：", err)
		return false
	}
	return true
}

func FirstMenuIsExists(ctx context.Context, firstMenu string) bool {
	o := orm.NewOrm()
	exist := o.QueryTable(MENUINFO).Filter("first_menu", firstMenu).ExistWithCtx(ctx)
	return exist
}

func FirstMenuUidIsExists(ctx context.Context, firstMenUid string) bool {
	o := orm.NewOrm()
	exist := o.QueryTable(MENUINFO).Filter("menu_uid", firstMenUid).ExistWithCtx(ctx)
	return exist
}

func MenuOrderIsExists(ctx context.Context, menuOrder int) bool {
	o := orm.NewOrm()
	exist := o.QueryTable(MENUINFO).Filter("menu_order", menuOrder).ExistWithCtx(ctx)
	return exist
}

func GetMenuLen(ctx context.Context) int {
	o := orm.NewOrm()
	cnt, err := o.QueryTable(MENUINFO).CountWithCtx(ctx)
	if err != nil {
		logs.Error("get menu info len length fail: ", err)
	}
	return int(cnt)
}

func GetMenuInfoByMenuUid(ctx context.Context, menuUid string) MenuInfo {
	o := orm.NewOrm()
	var menuInfo MenuInfo
	_, err := o.QueryTable(MENUINFO).Filter("menu_uid", menuUid).Limit(1).AllWithCtx(ctx, &menuInfo)
	if err != nil {
		logs.Error("get menu info by menuUid fail: ", err)
	}
	return menuInfo
}

func GetMenuInfosByMenuUids(ctx context.Context, menuUids []string) []MenuInfo {
	menuInfoList := make([]MenuInfo, 0)
	for _, v := range menuUids {
		m := GetMenuInfoByMenuUid(ctx, v)
		menuInfoList = append(menuInfoList, m)
	}
	return menuInfoList
}

func GetMenuInfoByMenuOrder(ctx context.Context, menuOrder int) MenuInfo {
	o := orm.NewOrm()
	var menuInfo MenuInfo
	_, err := o.QueryTable(MENUINFO).Filter("menu_order", menuOrder).Limit(1).AllWithCtx(ctx, &menuInfo)
	if err != nil {
		logs.Error("get menu info by menu order fail: ", err)
	}
	return menuInfo
}

func GetMenuAll(ctx context.Context) []MenuInfo {
	o := orm.NewOrm()
	var menuInfoList []MenuInfo
	_, err := o.QueryTable(MENUINFO).OrderBy("-update_time").AllWithCtx(ctx, &menuInfoList)
	if err != nil {
		logs.Error("get all menu list fail：", err)
	}
	return menuInfoList
}

func GetMenuOffsetByMap(ctx context.Context, params map[string]string, displayCount, offset int) []MenuInfo {
	o := orm.NewOrm()
	var menuInfoList []MenuInfo
	qs := o.QueryTable(MENUINFO)
	for k, v := range params {
		if len(v) > 0 {
			qs = qs.Filter(k, v)
		}
	}
	_, err := qs.Limit(displayCount, offset).OrderBy("-update_time").AllWithCtx(ctx, &menuInfoList)
	if err != nil {
		logs.Error("get menu offset by map fail: ", err)
	}
	return menuInfoList
}

func GetMenuLenByMap(ctx context.Context, params map[string]string) int {
	o := orm.NewOrm()
	qs := o.QueryTable(MENUINFO)
	for k, v := range params {
		if len(v) > 0 {
			qs = qs.Filter(k, v)
		}
	}
	cnt, err := qs.CountWithCtx(ctx)
	if err != nil {
		logs.Error("get menu len by map fail: ", err)
	}
	return int(cnt)
}

func UpdateMenuInfo(ctx context.Context, menuInfo MenuInfo) {
	o := orm.NewOrm()
	cnt, err := o.UpdateWithCtx(ctx, &menuInfo)
	if err != nil {
		logs.Error("update menu info fail: ", err)
	}
	logs.Info("update menu info success, num: ", cnt)
}

func DeleteMenuInfo(ctx context.Context, menuUid string) {
	o := orm.NewOrm()
	cnt, err := o.QueryTable(MENUINFO).Filter("menu_uid", menuUid).DeleteWithCtx(ctx)
	if err != nil {
		logs.Error("delete menu info fail: ", err)
	}
	logs.Info("delete menu info num: ", cnt)
}
