package dao

import (
	"fmt"
	"github.com/civet148/log"
	"github.com/civet148/sqlca/v2"
	"intent-system/pkg/dal/models"
)

type NewsDraftCondition struct {
	PageNo   int
	PageSize int
	Asc      bool
	Id       int64
	Search   string
}

type NewsDraftDAO struct {
	db *sqlca.Engine
}

func NewNewsDraftDAO(db *sqlca.Engine) *NewsDraftDAO {
	return &NewsDraftDAO{
		db: db,
	}
}

// insert into table by data model
func (dao *NewsDraftDAO) Insert(do *models.NewsDraftDO) (lastInsertId int64, err error) {
	return dao.db.Model(&do).Table(models.TableNameNewsDraft).Insert()
}

// insert if not exist or update columns on duplicate key...
func (dao *NewsDraftDAO) Upsert(do *models.NewsDraftDO, columns ...string) (lastInsertId int64, err error) {
	_, err = dao.db.Model(&do).
		Table(models.TableNameNewsDraft).
		Select(models.NEWS_DRAFT_COLUMN_ID).
		Eq(models.NEWS_DRAFT_COLUMN_NEWS_ID, do.NewsId).
		Eq(models.NEWS_DRAFT_COLUMN_IS_DELETED, 0).
		Query()
	if err != nil {
		return 0, log.Errorf(err.Error())
	}
	if do.Id != 0 {
		_, err = dao.db.Model(&do).Table(models.TableNameNewsDraft).Select(columns...).Update()
		if err != nil {
			return 0, log.Errorf(err.Error())
		}
		return do.Id, nil
	}
	return dao.db.Model(&do).Table(models.TableNameNewsDraft).Select(columns...).Insert()
}

// update table set columns where id=xxx
func (dao *NewsDraftDAO) Update(do *models.NewsDraftDO, columns ...string) (rows int64, err error) {
	return dao.db.Model(&do).Table(models.TableNameNewsDraft).Select(columns...).Update()
}

// query records by id
func (dao *NewsDraftDAO) QueryById(id interface{}, columns ...string) (do *models.NewsDraftDO, err error) {
	if _, err = dao.db.Model(&do).Table(models.TableNameNewsDraft).Id(id).Select(columns...).Query(); err != nil {
		return nil, err
	}
	return
}

func (dao *NewsDraftDAO) QueryList(cond *NewsDraftCondition) (dos []*models.NewsDraftDO, total int64, err error) {
	e := dao.db.Model(&dos).
		Table(models.TableNameNewsDraft).
		Eq(models.NEWS_DRAFT_COLUMN_IS_DELETED, 0).
		Page(cond.PageNo, cond.PageSize)

	if cond.Id != 0 {
		e.Eq(models.NEWS_DRAFT_COLUMN_ID, cond.Id)
	}
	if cond.Search != "" {
		e.Like(models.NEWS_DRAFT_COLUMN_MAIN_TITLE, cond.Search)
	}
	if cond.Asc {
		e.Asc(models.NEWS_DRAFT_COLUMN_UPDATED_TIME, models.NEWS_DRAFT_COLUMN_ID)
	} else {
		e.Desc(models.NEWS_DRAFT_COLUMN_UPDATED_TIME, models.NEWS_DRAFT_COLUMN_ID)
	}
	_, total, err = e.QueryEx()
	if err != nil {
		return nil, 0, log.Errorf(err.Error())
	}
	return
}

// query records by conditions
func (dao *NewsDraftDAO) QueryByCondition(conditions map[string]interface{}, columns ...string) (dos []*models.NewsDraftDO, err error) {
	if len(conditions) == 0 {
		return nil, fmt.Errorf("condition must not be empty")
	}
	e := dao.db.Model(&dos).Table(models.TableNameNewsDraft).Select(columns...)
	for k, v := range conditions {
		e.Eq(k, v)
	}
	if _, err = e.Query(); err != nil {
		return nil, err
	}
	return
}
