package utils

import (
	"errors"
	"github.com/go-xorm/xorm"
	"reflect"
)

// 分页插入数据库
func Insert(db *xorm.Engine, beans ...interface{}) error {
	return InsertWithSize(db, 500, beans...)
}

func InsertWithSize(db *xorm.Engine, size int, beans ...interface{}) error {
	if nil == db {
		return errors.New(`db can not be nil`)
	}

	if nil == beans || len(beans) == 0 {
		return nil
	}

	trans := db.NewSession()
	defer trans.Close()
	_ = trans.Begin()

	err := TransInsertWithSize(trans, size, beans...)
	if nil != err {
		_ = trans.Rollback()
		return err
	}

	return trans.Commit()
}

func TransInsert(trans *xorm.Session, beans ...interface{}) error {
	return TransInsertWithSize(trans, 500, beans...)
}

func TransInsertWithSize(trans *xorm.Session, size int, beans ...interface{}) error {
	if nil == trans {
		return errors.New(`trans can not be nil`)
	}

	if nil == beans || len(beans) == 0 {
		return nil
	}

	if size < 100 {
		size = 500
	}

	var objects []interface{}
	for _, bean := range beans {
		sliceValue := reflect.Indirect(reflect.ValueOf(bean))
		if sliceValue.Kind() == reflect.Slice {
			sLen := sliceValue.Len()
			if sLen == 0 {
				continue
			}
			if sLen <= size {
				objects = append(objects, bean)
				continue
			}
			idx := 0
			arrMap := make(map[int][]interface{})
			for i := 0; i < sliceValue.Len(); i++ {
				if i%size == 0 {
					idx++
				}
				v := sliceValue.Index(i)
				if v.Kind() == reflect.Ptr {
					v = v.Elem()
				}
				elemValue := v.Interface()
				if nil == arrMap[idx] {
					arrMap[idx] = []interface{}{elemValue}
				} else {
					arrMap[idx] = append(arrMap[idx], elemValue)
				}
			}
			for i := 1; i <= idx; i++ {
				arr := arrMap[i]
				objects = append(objects, &arr)
			}
		} else {
			objects = append(objects, bean)
		}
	}

	_, err := trans.Insert(objects...)
	if nil != err {
		return err
	}
	return nil
}