package speech_recognition

import (
	"eta/eta_mobile/utils"
	"fmt"
	"github.com/beego/beego/v2/client/orm"
	"strings"
	"time"
)

const (
	SpeechRecognitionTagMenuNodeTypeDefault = 0
	SpeechRecognitionTagMenuNodeTypeTag     = 1
)

// SpeechRecognitionTagMenu 标签目录表
type SpeechRecognitionTagMenu struct {
	SpeechRecognitionTagMenuId int       `orm:"column(speech_recognition_tag_menu_id);pk"`
	UniqueCode                 string    `description:"唯一编码"`
	MenuName                   string    `description:"目录名称"`
	ParentId                   int       `description:"父级ID"`
	Level                      int       `description:"目录层级"`
	Sort                       int       `description:"排序"`
	RootId                     int       `description:"顶级ID"`
	CreateTime                 time.Time `description:"创建时间"`
	ModifyTime                 time.Time `description:"修改时间"`
}

var SpeechRecognitionTagMenuCols = struct {
	SpeechRecognitionTagMenuId string
	UniqueCode                 string
	MenuName                   string
	ParentId                   string
	Level                      string
	Sort                       string
	RootId                     string
	CreateTime                 string
	ModifyTime                 string
}{
	SpeechRecognitionTagMenuId: "speech_recognition_tag_menu_id",
	UniqueCode:                 "unique_code",
	MenuName:                   "menu_name",
	ParentId:                   "parent_id",
	Level:                      "level",
	Sort:                       "sort",
	RootId:                     "root_id",
	CreateTime:                 "create_time",
	ModifyTime:                 "modify_time",
}

func (m *SpeechRecognitionTagMenu) TableName() string {
	return "speech_recognition_tag_menu"
}

func (m *SpeechRecognitionTagMenu) PrimaryId() string {
	return SpeechRecognitionTagMenuCols.SpeechRecognitionTagMenuId
}

func (m *SpeechRecognitionTagMenu) Create() (err error) {
	o := orm.NewOrm()
	id, err := o.Insert(m)
	if err != nil {
		return
	}
	m.SpeechRecognitionTagMenuId = int(id)
	return
}

func (m *SpeechRecognitionTagMenu) CreateMulti(items []*SpeechRecognitionTagMenu) (err error) {
	if len(items) == 0 {
		return
	}
	o := orm.NewOrm()
	_, err = o.InsertMulti(len(items), items)
	return
}

func (m *SpeechRecognitionTagMenu) Update(cols []string) (err error) {
	o := orm.NewOrm()
	_, err = o.Update(m, cols...)
	return
}

func (m *SpeechRecognitionTagMenu) Del() (err error) {
	o := orm.NewOrm()
	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
	_, err = o.Raw(sql, m.SpeechRecognitionTagMenuId).Exec()
	return
}

func (m *SpeechRecognitionTagMenu) MultiDel(menuIds []int) (err error) {
	if len(menuIds) == 0 {
		return
	}
	o := orm.NewOrm()
	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s IN (%s)`, m.TableName(), m.PrimaryId(), utils.GetOrmInReplace(len(menuIds)))
	_, err = o.Raw(sql, menuIds).Exec()
	return
}

func (m *SpeechRecognitionTagMenu) GetItemById(id int) (item *SpeechRecognitionTagMenu, err error) {
	o := orm.NewOrm()
	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
	err = o.Raw(sql, id).QueryRow(&item)
	return
}

func (m *SpeechRecognitionTagMenu) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *SpeechRecognitionTagMenu, err error) {
	o := orm.NewOrm()
	order := ``
	if orderRule != "" {
		order = ` ORDER BY ` + orderRule
	}
	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s %s LIMIT 1`, m.TableName(), condition, order)
	err = o.Raw(sql, pars).QueryRow(&item)
	return
}

func (m *SpeechRecognitionTagMenu) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
	o := orm.NewOrm()
	sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
	err = o.Raw(sql, pars).QueryRow(&count)
	return
}

func (m *SpeechRecognitionTagMenu) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*SpeechRecognitionTagMenu, err error) {
	o := orm.NewOrm()
	fields := strings.Join(fieldArr, ",")
	if len(fieldArr) == 0 {
		fields = `*`
	}
	order := `ORDER BY create_time DESC`
	if orderRule != "" {
		order = ` ORDER BY ` + orderRule
	}
	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
	_, err = o.Raw(sql, pars).QueryRows(&items)
	return
}

func (m *SpeechRecognitionTagMenu) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*SpeechRecognitionTagMenu, err error) {
	o := orm.NewOrm()
	fields := strings.Join(fieldArr, ",")
	if len(fieldArr) == 0 {
		fields = `*`
	}
	order := `ORDER BY create_time DESC`
	if orderRule != "" {
		order = ` ORDER BY ` + orderRule
	}
	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s LIMIT ?,?`, fields, m.TableName(), condition, order)
	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
	return
}

// SpeechRecognitionTagMenuItem 标签目录
type SpeechRecognitionTagMenuItem struct {
	UniqueCode string                          `description:"唯一编码"`
	MenuId     int                             `description:"目录ID"`
	MenuName   string                          `description:"目录名称"`
	ParentId   int                             `description:"父级ID"`
	Level      int                             `description:"目录层级"`
	Sort       int                             `description:"排序"`
	CreateTime string                          `description:"创建时间"`
	Children   []*SpeechRecognitionTagMenuItem `description:"子目录"`
}

// SpeechRecognitionTagMenuNodeItem 标签目录树节点
type SpeechRecognitionTagMenuNodeItem struct {
	UniqueCode string                              `description:"唯一编码"`
	NodeType   int                                 `description:"节点类型：0-目录；1-标签"`
	MenuId     int                                 `description:"目录ID"`
	MenuName   string                              `description:"目录名称"`
	TagId      int                                 `description:"标签ID"`
	TagName    string                              `description:"标签名称"`
	ParentId   int                                 `description:"父级ID"`
	Level      int                                 `description:"目录层级"`
	Sort       int                                 `description:"排序"`
	CreateTime string                              `description:"创建时间"`
	Children   []*SpeechRecognitionTagMenuNodeItem `description:"子节点"`
}

// SpeechRecognitionTagMenuAddReq 新增标签目录
type SpeechRecognitionTagMenuAddReq struct {
	ParentId int    `description:"父级ID"`
	MenuName string `description:"目录名称"`
}

// SpeechRecognitionTagMenuEditReq 编辑标签目录
type SpeechRecognitionTagMenuEditReq struct {
	MenuId   int    `description:"目录ID"`
	MenuName string `description:"目录名称"`
}

// SpeechRecognitionTagMenuRemoveReq 删除标签目录
type SpeechRecognitionTagMenuRemoveReq struct {
	MenuId int `description:"目录ID"`
}

// SpeechRecognitionTagMenuMoveReq 移动目录请求体
type SpeechRecognitionTagMenuMoveReq struct {
	MenuId       int `description:"目录ID"`
	ParentMenuId int `description:"父级目录ID"`
	PrevMenuId   int `description:"上一个兄弟节点目录ID"`
	NextMenuId   int `description:"下一个兄弟节点目录ID"`
	TagId        int `description:"标签ID, 大于0则表示移动标签"`
	PrevTagId    int `description:"上一个标签ID"`
	NextTagId    int `description:"下一个标签ID"`
}

// UpdateSortByParentId 根据父级ID更新排序
func (m *SpeechRecognitionTagMenu) UpdateSortByParentId(parentId, menuId, nowSort int, updateSort string) (err error) {
	o := orm.NewOrm()
	sql := fmt.Sprintf(`UPDATE %s SET %s = %s WHERE %s = ? AND %s > ?`, m.TableName(), SpeechRecognitionTagMenuCols.Sort, updateSort, SpeechRecognitionTagMenuCols.ParentId, SpeechRecognitionTagMenuCols.Sort)
	if menuId > 0 {
		sql += fmt.Sprintf(` OR (%s > %d AND %s = %d)`, SpeechRecognitionTagMenuCols.SpeechRecognitionTagMenuId, menuId, SpeechRecognitionTagMenuCols.Sort, nowSort)
	}
	_, err = o.Raw(sql, parentId, nowSort).Exec()
	return
}

// GetMaxSortByParentId 获取父级分类下最大Sort
func (m *SpeechRecognitionTagMenu) GetMaxSortByParentId(parentId int) (sort int, err error) {
	o := orm.NewOrm()
	sql := fmt.Sprintf(`SELECT MAX(sort) AS sort FROM %s WHERE %s = ?`, m.TableName(), SpeechRecognitionTagMenuCols.ParentId)
	err = o.Raw(sql, parentId).QueryRow(&sort)
	return
}

// GetFirstByParentId 获取父级目录下排序第一的目录
func (m *SpeechRecognitionTagMenu) GetFirstByParentId(parentId int) (item *SpeechRecognitionTagMenu, err error) {
	o := orm.NewOrm()
	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? ORDER BY %s ASC, %s ASC LIMIT 1`, m.TableName(), SpeechRecognitionTagMenuCols.ParentId, SpeechRecognitionTagMenuCols.Sort, SpeechRecognitionTagMenuCols.SpeechRecognitionTagMenuId)
	err = o.Raw(sql, parentId).QueryRow(&item)
	return
}

// UpdateChildByParentMenuId 通过父级目录ID更新子目录
func (m *SpeechRecognitionTagMenu) UpdateChildByParentMenuId(menuIds []int, rootId int, levelStep int) (err error) {
	if len(menuIds) == 0 {
		return
	}
	o := orm.NewOrm()
	var pars []interface{}
	pars = append(pars, rootId, levelStep)
	pars = append(pars, menuIds)
	sql := fmt.Sprintf(`UPDATE %s SET %s = ?, %s = %s + ? WHERE %s IN (%s)`, m.TableName(), SpeechRecognitionTagMenuCols.RootId, SpeechRecognitionTagMenuCols.Level, SpeechRecognitionTagMenuCols.Level, SpeechRecognitionTagMenuCols.SpeechRecognitionTagMenuId, utils.GetOrmInReplace(len(menuIds)))
	_, err = o.Raw(sql, pars).Exec()
	return
}
