package app

import (
	"fmt"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"miniapp/global"
)

// 分页组件
func Page(current, size int) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if current == 0 {
			current = 1
		}
		if size < 1 {
			size = 10
		}
		// 计算偏移量
		offset := (current - 1) * size
		// 返回组装结果
		return db.Offset(offset).Limit(size)
	}
}

// @title updateSortBefore
// @description 更新之前处理序号
// @param tx *gorm.DB "已开启的事务对象"
// @param model any "模型对象"
// @return error "错误信息"
func updateSortBefore(tx *gorm.DB, tableName, id string, sort int, param string) (err error) {
	// 查出原来的排序号
	var oldSort int
	err = tx.Table(tableName).Select("sort").Where("id = ?", id).Scan(&oldSort).Error
	if err != nil {
		global.GVA_LOG.Error("查询老数据失败: %v", zap.Error(err))
		return
	}
	// 如果相等，啥都不干
	if oldSort == sort {
		return nil
	}
	// 处理排序
	// 如果老的排序号小于新的，(老, 新]之间的排序号都要-1
	// 如果老的大于新的，[老, 新)排序号-1
	if oldSort < sort {
		// 老的小于新的，[老, 新) + 1
		sel := tx.Table(tableName).
			Where("sort <= ? AND sort > ?", sort, oldSort).
			Where("deleted_at IS NULL")
		if param != "" {
			sel.Where(param) // 自定义条件
		}
		err = sel.Update("sort", gorm.Expr("sort - 1")).Error
	} else {
		// 老的大于新的，[新, 老) + 1
		sel := tx.Table(tableName).
			Where("sort >= ? AND sort < ?", sort, oldSort).
			Where("deleted_at IS NULL")
		if param != "" {
			sel.Where(param) // 自定义条件
		}
		err = sel.Update("sort", gorm.Expr("sort + 1")).Error
	}
	return
}

// @title createSortBefore
// @description 新建之前处理序号
// @param tx *gorm.DB "已开启的事务对象"
// @param model any "模型对象"
// @return error "错误信息"
func createSortBefore(tx *gorm.DB, tableName string, sort int, param string) (err error) {
	// 处理排序,如果没有传，就会是在最前面
	sel := tx.Table(tableName).Where("sort >= ?", sort).
		Where("deleted_at IS NULL")
	if param != "" {
		sel.Where(param)
	}
	err = sel.Update("sort", gorm.Expr("sort + 1")).Error
	if err != nil {
		global.GVA_LOG.Error("处理前置排序失败：%v", zap.Error(err))
	}
	return
}

// @title dealSortAfter
// @description 处理序号之后
// @param tx *gorm.DB "已开启的事务对象"
// @param modelName string "表名"
// @return error "错误信息"
func dealSortAfter(tx *gorm.DB, modelName, param string) (err error) {
	// 保存成功，刷新排序
	if param != "" {
		param += " AND "
	}
	sql := fmt.Sprintf("UPDATE %s a, (SELECT (@i := @i + 1) i, id FROM %s WHERE %s deleted_at IS NULL order by sort ASC) i, "+
		"(SELECT @i := 0) ir SET a.sort = i.i, updated_at=now() WHERE a.id = i.id", modelName, modelName, param)
	err = tx.Exec(sql).Error
	if err != nil {
		global.GVA_LOG.Error("刷新排序失败: %v", zap.Error(err))
	}
	return
}
