package actions

import (
	"errors"
	"github.com/gin-gonic/gin"
	log "gogs.baozhida.cn/zoie/OAuth-core/logger"
	"gogs.baozhida.cn/zoie/OAuth-core/pkg"
	"gogs.baozhida.cn/zoie/OAuth-core/pkg/jwtauth/user"
	"gogs.baozhida.cn/zoie/OAuth-core/pkg/response"
	"gogs.baozhida.cn/zoie/OAuth-core/sdk/config"
	"gorm.io/gorm"
)

type DataPermission struct {
	DataScope string
	UserType  string
	UserId    int
	DeptId    int
	RoleId    int
}

func PermissionAction() gin.HandlerFunc {
	return func(c *gin.Context) {
		ormDB, err := pkg.GetOrm(c)
		if err != nil {
			log.Error(err)
			return
		}

		msgID := pkg.GenerateMsgIDFromContext(c)
		var p = new(DataPermission)
		if userId := user.GetUserIdStr(c); userId != "" {
			p, err = newDataPermission(ormDB, userId)
			if err != nil {
				log.Errorf("MsgID[%s] PermissionAction error: %s", msgID, err)
				response.Error(c, 500, err, "权限范围鉴定错误")
				c.Abort()
				return
			}
		}
		c.Set(PermissionKey, p)
		c.Next()
	}
}

func newDataPermission(tx *gorm.DB, userId interface{}) (*DataPermission, error) {
	var err error
	p := &DataPermission{}

	//err = tx.Table("sys_user").
	//	Select("sys_user.id as user_id", "sys_role.id as role_id", "sys_user.dept_id", "sys_role.data_scope").
	//	Joins("left join sys_role on sys_role.id = sys_user.role_id").
	//	Where("sys_user.id = ?", userId).
	//	Scan(p).Error
	err = tx.Table("sys_user").
		Select("sys_user.id as user_id", "sys_user.dept_id", "sys_user.user_type").
		Where("sys_user.id = ?", userId).
		Scan(p).Error
	if err != nil {
		err = errors.New("获取用户数据出错 msg:" + err.Error())
		return nil, err
	}
	return p, nil
}

func UserPermission(tableName string, p *DataPermission) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if !config.ApplicationConfig.EnableDP {
			return db
		}
		if p == nil {
			return db
		}
		switch p.DataScope {
		//case "2":
		//	return db.Where(tableName+".create_by in (select sys_user.id from sys_role_dept left join sys_user on sys_user.dept_id=sys_role_dept.dept_id where sys_role_dept.role_id = ?) id = ?", p.RoleId, p.UserIds)
		case "3":
			return db.Where(tableName+".dept_id = ? ", p.DeptId)
		case "4":
			return db.Where(tableName+".create_by in (SELECT id from sys_user where sys_user.dept_id in(select id from sys_dept where dept_path like ? )) or id = ?", "%/"+pkg.IntToString(p.DeptId)+"/%", p.UserId)
		case "5":
			return db.Where(tableName+".id = ?", p.UserId)
		default:
			return db
		}
	}
}

func Permission(tableName string, p *DataPermission) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if !config.ApplicationConfig.EnableDP {
			return db
		}
		if p == nil {
			return db
		}
		switch p.DataScope {
		//case "2":
		//	return db.Where(tableName+".create_by in (select sys_user.id from sys_role_dept left join sys_user on sys_user.dept_id=sys_role_dept.dept_id where sys_role_dept.role_id = ?)", p.RoleId)
		case "3":
			return db.Where(tableName+".dept_id = ?", p.DeptId)
		case "4":
			return db.Where(tableName+".create_by in (SELECT id from sys_user where sys_user.dept_id in (select id from sys_dept where dept_path like ? ))", "%/"+pkg.IntToString(p.DeptId)+"/%")
		case "5":
			return db.Where(tableName+".create_by = ?", p.UserId)
		default:
			return db
		}
	}
}

func getPermissionFromContext(c *gin.Context) *DataPermission {
	p := new(DataPermission)
	if pm, ok := c.Get(PermissionKey); ok {
		switch pm.(type) {
		case *DataPermission:
			p = pm.(*DataPermission)
		}
	}
	p.DataScope = "3"
	return p
}

// GetPermissionFromContext 提供非action写法数据范围约束
func GetPermissionFromContext(c *gin.Context) *DataPermission {
	return getPermissionFromContext(c)
}
