package speech_recognition

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

const (
	SpeechRecognitionMenuNodeTypeDefault = 0
	SpeechRecognitionMenuNodeTypeSpeech  = 1
)

// SpeechRecognitionMenu 语音识别-目录表
type SpeechRecognitionMenu struct {
	SpeechRecognitionMenuId int       `orm:"column(speech_recognition_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 SpeechRecognitionMenuCols = struct {
	SpeechRecognitionMenuId string
	UniqueCode              string
	MenuName                string
	ParentId                string
	Level                   string
	Sort                    string
	RootId                  string
	CreateTime              string
	ModifyTime              string
}{
	SpeechRecognitionMenuId: "speech_recognition_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 *SpeechRecognitionMenu) TableName() string {
	return "speech_recognition_menu"
}

func (m *SpeechRecognitionMenu) PrimaryId() string {
	return SpeechRecognitionMenuCols.SpeechRecognitionMenuId
}

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

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

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

func (m *SpeechRecognitionMenu) 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.SpeechRecognitionMenuId).Exec()
	return
}

func (m *SpeechRecognitionMenu) 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 *SpeechRecognitionMenu) GetItemById(id int) (item *SpeechRecognitionMenu, 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 *SpeechRecognitionMenu) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *SpeechRecognitionMenu, 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 *SpeechRecognitionMenu) 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 *SpeechRecognitionMenu) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*SpeechRecognitionMenu, 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 *SpeechRecognitionMenu) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*SpeechRecognitionMenu, 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
}

// SpeechRecognitionMenuItem 目录
type SpeechRecognitionMenuItem 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   []*SpeechRecognitionMenuItem `description:"子目录"`
}

// SpeechRecognitionMenuNodeItem 语音识别目录节点
type SpeechRecognitionMenuNodeItem struct {
	UniqueCode            string                           `description:"唯一编码"`
	NodeType              int                              `description:"节点类型:0-目录;1-语音识别"`
	MenuId                int                              `description:"目录ID"`
	MenuName              string                           `description:"目录名称"`
	SpeechRecognitionId   int                              `description:"语音识别ID"`
	SpeechRecognitionName string                           `description:"语音识别名称"`
	ParentId              int                              `description:"父级ID"`
	Level                 int                              `description:"目录层级"`
	Sort                  int                              `description:"排序"`
	CreateTime            string                           `description:"创建时间"`
	Children              []*SpeechRecognitionMenuNodeItem `description:"子节点"`
}

// SpeechRecognitionMenuAddReq 新增语音识别目录
type SpeechRecognitionMenuAddReq struct {
	ParentId int    `description:"父级ID"`
	MenuName string `description:"目录名称"`
}

// SpeechRecognitionMenuEditReq 编辑语音识别目录
type SpeechRecognitionMenuEditReq struct {
	MenuId   int    `description:"目录ID"`
	MenuName string `description:"目录名称"`
}

// SpeechRecognitionMenuRemoveReq 删除语音识别目录
type SpeechRecognitionMenuRemoveReq struct {
	MenuId int `description:"目录ID"`
}

// SpeechRecognitionMenuRemoveCheckResp 删除语音识别目录-响应体
type SpeechRecognitionMenuRemoveCheckResp struct {
	CheckResult int    `description:"校验结果:0-可删除;1-关联内容;2-关联空目录"`
	Tips        string `description:"提示信息"`
}

// SpeechRecognitionMenuMoveReq 移动目录请求体
type SpeechRecognitionMenuMoveReq struct {
	MenuId       int `description:"目录ID"`
	ParentMenuId int `description:"父级目录ID"`
	PrevMenuId   int `description:"上一个兄弟节点目录ID"`
	NextMenuId   int `description:"下一个兄弟节点目录ID"`
	SpeechId     int `description:"语音识别ID, 大于0则表示移动语音识别"`
	PrevSpeechId int `description:"上一个语音识别ID"`
	NextSpeechId int `description:"下一个语音识别ID"`
}

// UpdateSortByParentId 根据父级ID更新排序
func (m *SpeechRecognitionMenu) 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(), SpeechRecognitionMenuCols.Sort, updateSort, SpeechRecognitionMenuCols.ParentId, SpeechRecognitionMenuCols.Sort)
	if menuId > 0 {
		sql += fmt.Sprintf(` OR (%s > %d AND %s = %d)`, SpeechRecognitionMenuCols.SpeechRecognitionMenuId, menuId, SpeechRecognitionMenuCols.Sort, nowSort)
	}
	_, err = o.Raw(sql, parentId, nowSort).Exec()
	return
}

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

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

// UpdateChildByParentMenuId 通过父级目录ID更新子目录
func (m *SpeechRecognitionMenu) 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(), SpeechRecognitionMenuCols.RootId, SpeechRecognitionMenuCols.Level, SpeechRecognitionMenuCols.Level, SpeechRecognitionMenuCols.SpeechRecognitionMenuId, utils.GetOrmInReplace(len(menuIds)))
	_, err = o.Raw(sql, pars).Exec()
	return
}