package utils

import (
	"strconv"
)

type PageNaviEngine struct {
	ctx *Context
}

func NewPageNaviEngine(ctx *Context) *PageNaviEngine {
	return &PageNaviEngine{ctx: ctx}
}

// GetPageList 获取列表
func (t *PageNaviEngine) GetPageList(target interface{}, sql string, limit []int, sqlArgs ...interface{}) (int64, error) {
	countSQL := "select count(*) as cnt from (" + sql + ") as virtualTable"
	countSQLorArgs := []interface{}{countSQL}
	for _, arg := range sqlArgs {
		countSQLorArgs = append(countSQLorArgs, arg)
	}

	cntRes, err := t.ctx.DB.Query(countSQLorArgs...)
	if err != nil {
		return 0, err
	}

	cntStr := string(cntRes[0]["cnt"])
	cnt, _ := strconv.ParseInt(cntStr, 10, 64)

	newSQL := t.PackLimitToSQL(sql, limit)

	err = t.ctx.DB.SQL(newSQL, sqlArgs...).Find(target)
	if err != nil {
		return 0, err
	}

	return cnt, nil
}

// PackLimitToSQL 添加 limit 语句到 sql 最后
func (t *PageNaviEngine) PackLimitToSQL(sql string, limit []int) string {
	switch len(limit) {
	case 1:
		return sql + " LIMIT " + strconv.Itoa(limit[0])
	case 2:
		return sql + " LIMIT " + strconv.Itoa(limit[0]) + " OFFSET " + strconv.Itoa(limit[1])
	default:
		return sql
	}
}