//
// Copyright (C) 2024 veypi <i@veypi.com>
// 2024-09-20 16:10:16
// Distributed under terms of the MIT license.
//

package models

import (
	"strings"

	"github.com/veypi/vbase/cfg"

	"github.com/google/uuid"
	"github.com/veypi/vigo"
	"github.com/veypi/vigo/logv"
)

var AllModels = &vigo.ModelList{}

func init() {
	AllModels.Append(User{}, AppUser{}, Resource{}, Access{}, Role{}, UserRole{}, Token{}, App{}, SMSCode{}, SMSLog{})
}

func Migrate() error {
	return AllModels.AutoMigrate(cfg.DB())
}

func Drop() error {
	return AllModels.AutoDrop(cfg.DB())
}

func InitDB() error {
	app := &App{}
	app.ID = cfg.Config.ID
	app.Name = "OA"
	app.Icon = "/favicon.ico"
	app.Key = cfg.Config.Key
	logv.AssertError(cfg.DB().Where("id = ?", app.ID).Attrs(app).FirstOrCreate(app).Error)
	initRole := map[string]map[string]uint{
		"user": {"admin": 5, "normal": 1},
		"app":  {"admin": 5, "normal": 1},
	}
	adminID := ""
	for r, roles := range initRole {
		resource := &Resource{
			AppID: app.ID,
			Name:  r,
		}
		logv.AssertError(cfg.DB().Where("app_id = ? AND name = ?", app.ID, r).FirstOrCreate(resource).Error)
		for rName, l := range roles {
			role := &Role{}
			logv.AssertError(cfg.DB().Where("app_id = ? AND name = ?", app.ID, rName).Attrs(&Role{
				Model: vigo.Model{
					ID: strings.ReplaceAll(uuid.New().String(), "-", ""),
				},
				AppID: app.ID,
				Name:  rName,
			}).FirstOrCreate(role).Error)
			logv.AssertError(cfg.DB().Where("app_id = ? AND role_id = ? AND name = ?", app.ID, role.ID, r).FirstOrCreate(&Access{
				AppID:      app.ID,
				RoleID:     &role.ID,
				ResourceID: &resource.ID,
				Name:       r,
				Level:      l,
			}).Error)
			if rName == "admin" {
				adminID = role.ID
			}
		}
	}
	if app.InitRoleID == nil {
		logv.AssertError(cfg.DB().Model(app).Update("init_role_id", adminID).Error)
	}
	return nil
}
