package eta_training_video

import (
	"fmt"
	"github.com/beego/beego/v2/client/orm"
	"github.com/rdlucklib/rdluck_tools/paging"
	"strings"
	"time"
)

const (
	VideoUnPublish = 0
	VideoPublished = 1
)

// EtaTrainingVideo ETA培训视频
type EtaTrainingVideo struct {
	EtaTrainingVideoId int       `orm:"column(eta_training_video_id);pk"`
	VideoCode          string    `description:"视频唯一编码"`
	Title              string    `description:"视频标题"`
	Introduce          string    `description:"视频简介"`
	ClassifyIds        string    `description:"视频分类IDs, 英文逗号拼接"`
	TagIds             string    `description:"标签IDs, 英文逗号拼接"`
	CoverImg           string    `description:"封面图"`
	VideoUrl           string    `description:"视频地址"`
	PublishState       int       `description:"发布状态：0-未发布; 1-已发布"`
	PublishTime        time.Time `description:"发布时间"`
	ViewTotal          int       `description:"访问量"`
	CreateTime         time.Time `description:"创建时间"`
	ModifyTime         time.Time `description:"更新时间"`
}

func (m *EtaTrainingVideo) TableName() string {
	return "eta_training_video"
}

func (m *EtaTrainingVideo) PrimaryId() string {
	return VideoColumns.EtaTrainingVideoId
}

var VideoColumns = struct {
	EtaTrainingVideoId string
	VideoCode          string
	Title              string
	Introduce          string
	ClassifyIds        string
	TagIds             string
	CoverImg           string
	VideoUrl           string
	PublishState       string
	PublishTime        string
	ViewTotal          string
	CreateTime         string
	ModifyTime         string
}{
	EtaTrainingVideoId: "eta_training_video_id",
	VideoCode:          "video_code",
	Title:              "title",
	Introduce:          "introduce",
	ClassifyIds:        "classify_ids",
	TagIds:             "tag_ids",
	CoverImg:           "cover_img",
	VideoUrl:           "video_url",
	PublishState:       "publish_state",
	PublishTime:        "publish_time",
	ViewTotal:          "view_total",
	CreateTime:         "create_time",
	ModifyTime:         "modify_time",
}

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

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

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

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

func (m *EtaTrainingVideo) GetItemById(id int) (item *EtaTrainingVideo, 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 *EtaTrainingVideo) GetItemByCondition(condition string, pars []interface{}) (item *EtaTrainingVideo, err error) {
	o := orm.NewOrm()
	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s LIMIT 1`, m.TableName(), condition)
	err = o.Raw(sql, pars).QueryRow(&item)
	return
}

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

func (m *EtaTrainingVideo) CreateVideoAndRelates(videoItem *EtaTrainingVideo, classifyRelates []*EtaTrainingVideoClassifyRelate, tagRelates []*EtaTrainingVideoTagRelate) (err error) {
	o := orm.NewOrm()
	tx, err := o.Begin()
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			_ = tx.Rollback()
			return
		}
		_ = tx.Commit()
	}()

	id, e := tx.Insert(videoItem)
	if e != nil {
		err = fmt.Errorf("insert video err: %s", e.Error())
		return
	}
	videoItem.EtaTrainingVideoId = int(id)

	if len(classifyRelates) > 0 {
		for _, cr := range classifyRelates {
			cr.EtaTrainingVideoId = videoItem.EtaTrainingVideoId
		}
		if _, e = tx.InsertMulti(len(classifyRelates), classifyRelates); e != nil {
			err = fmt.Errorf("insert multi classify relates err: %s", e.Error())
			return
		}
	}
	if len(tagRelates) > 0 {
		for _, tr := range tagRelates {
			tr.EtaTrainingVideoId = videoItem.EtaTrainingVideoId
		}
		if _, e = tx.InsertMulti(len(tagRelates), tagRelates); e != nil {
			err = fmt.Errorf("insert multi tag relates err: %s", e.Error())
			return
		}
	}
	return
}

func (m *EtaTrainingVideo) UpdateVideoAndRelates(videoItem *EtaTrainingVideo, updateCols []string, classifyRelates []*EtaTrainingVideoClassifyRelate, tagRelates []*EtaTrainingVideoTagRelate) (err error) {
	if videoItem.EtaTrainingVideoId <= 0 {
		return
	}
	o := orm.NewOrm()
	tx, err := o.Begin()
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			_ = tx.Rollback()
			return
		}
		_ = tx.Commit()
	}()

	if len(updateCols) > 0 {
		_, e := tx.Update(videoItem, updateCols...)
		if e != nil {
			err = fmt.Errorf("update video err: %s", e.Error())
			return
		}
	}

	// 分类
	sql := `DELETE FROM eta_training_video_classify_relate WHERE eta_training_video_id = ?`
	if _, e := tx.Raw(sql, videoItem.EtaTrainingVideoId).Exec(); e != nil {
		err = fmt.Errorf("clear classify relates err: %s", e.Error())
		return
	}
	if len(classifyRelates) > 0 {
		for _, cr := range classifyRelates {
			cr.EtaTrainingVideoId = videoItem.EtaTrainingVideoId
		}
		if _, e := tx.InsertMulti(len(classifyRelates), classifyRelates); e != nil {
			err = fmt.Errorf("insert multi classify relates err: %s", e.Error())
			return
		}
	}

	// 标签
	sql = `DELETE FROM eta_training_video_tag_relate WHERE eta_training_video_id = ?`
	if _, e := tx.Raw(sql, videoItem.EtaTrainingVideoId).Exec(); e != nil {
		err = fmt.Errorf("clear tag relates err: %s", e.Error())
		return
	}
	if len(tagRelates) > 0 {
		for _, tr := range tagRelates {
			tr.EtaTrainingVideoId = videoItem.EtaTrainingVideoId
		}
		if _, e := tx.InsertMulti(len(tagRelates), tagRelates); e != nil {
			err = fmt.Errorf("insert multi tag relates err: %s", e.Error())
			return
		}
	}
	return
}

// EtaTrainingVideoAddReq 新增视频请求体
type EtaTrainingVideoAddReq struct {
	Title      string `description:"视频标题"`
	Introduce  string `description:"视频简介"`
	CoverImg   string `description:"封面图"`
	VideoUrl   string `description:"视频地址"`
	ClassifyId int    `description:"分类ID"`
	TagIds     []int  `description:"标签IDs"`
}

// EtaTrainingVideoEditReq 编辑视频请求体
type EtaTrainingVideoEditReq struct {
	VideoId int `description:"视频ID"`
	EtaTrainingVideoAddReq
}

// EtaTrainingVideoPublishReq 发布/取消发布视频请求体
type EtaTrainingVideoPublishReq struct {
	VideoId      int `description:"视频ID"`
	PublishState int `description:"发布状态：0-取消发布；1-发布"`
}

// EtaTrainingVideoRemoveReq 删除视频请求体
type EtaTrainingVideoRemoveReq struct {
	VideoId int `description:"视频ID"`
}

// EtaTrainingVideoListResp 视频分页列表响应体
type EtaTrainingVideoListResp struct {
	List   []*EtaTrainingVideoItem `description:"视频列表数据"`
	Paging *paging.PagingItem      `description:"分页数据"`
}

// EtaTrainingVideoItem ETA视频信息
type EtaTrainingVideoItem struct {
	VideoId      int                           `description:"视频ID"`
	VideoCode    string                        `description:"视频唯一编码"`
	Title        string                        `description:"视频标题"`
	Introduce    string                        `description:"视频简介"`
	Classify     *EtaTrainingVideoClassifyItem `description:"视频分类"`
	Tags         []*EtaTrainingVideoTagItem    `description:"视频标签"`
	CoverImg     string                        `description:"封面图"`
	VideoUrl     string                        `description:"视频地址"`
	PublishState int                           `description:"发布状态：0-未发布；1-已发布"`
	PublishTime  string                        `description:"发布时间"`
	ViewTotal    int                           `description:"访问量"`
	CreateTime   string                        `description:"创建时间"`
	ModifyTime   string                        `description:"更新时间"`
}
