package tool

import (
	"github.com/pkg/errors"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

// APIEntity API实体接口
type APIEntity interface {
	GetPath() string
	GetMethod() string
	GetAPIGroup() string
}

// MenuEntity 菜单实体接口
type MenuEntity interface {
	GetName() string
	SetParentID(id int64)
}

// RegisterApis 注册API到数据库（通用版本）
func RegisterApis[T APIEntity](db *gorm.DB, model T, apis ...T) {
	err := db.Transaction(func(tx *gorm.DB) error {
		for _, api := range apis {
			err := tx.Model(model).Where("path = ? AND method = ? AND api_group = ? ", api.GetPath(), api.GetMethod(), api.GetAPIGroup()).FirstOrCreate(&api).Error
			if err != nil {
				zap.L().Error("注册API失败", zap.Error(err), zap.String("api", api.GetPath()), zap.String("method", api.GetMethod()), zap.String("apiGroup", api.GetAPIGroup()))
				return err
			}
		}
		return nil
	})
	if err != nil {
		zap.L().Error("注册API失败", zap.Error(err))
	}
}

// RegisterMenus 注册菜单到数据库（通用版本）
func RegisterMenus[T MenuEntity](db *gorm.DB, model T, menus ...T) {
	if len(menus) == 0 {
		return
	}
	parentMenu := menus[0]
	otherMenus := menus[1:]
	err := db.Transaction(func(tx *gorm.DB) error {
		err := tx.Model(model).Where("name = ? ", parentMenu.GetName()).FirstOrCreate(&parentMenu).Error
		if err != nil {
			zap.L().Error("注册菜单失败", zap.Error(err))
			return errors.Wrap(err, "注册菜单失败")
		}
		// 获取父菜单ID需要通过反射或其他方式
		for i := range otherMenus {
			err = tx.Model(model).Where("name = ? ", otherMenus[i].GetName()).FirstOrCreate(&otherMenus[i]).Error
			if err != nil {
				zap.L().Error("注册菜单失败", zap.Error(err))
				return errors.Wrap(err, "注册菜单失败")
			}
		}

		return nil
	})
	if err != nil {
		zap.L().Error("注册菜单失败", zap.Error(err))
	}
}
