package migrate

import (
	"context"
	"errors"
	"time"

	"github.com/tidbcloud/account/commons/config"
	"github.com/tidbcloud/account/internel/dao/entity"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"gorm.io/gorm"
)

func initCentralDB(db *gorm.DB) error {
	ctx := context.Background()

	tilog.Info(ctx, "init empty database with data")
	// create the tables in a empty database
	// it is 3 time faster than migrate model individually
	if err := db.AutoMigrate(entity.Models...); err != nil {
		return err
	}
	tilog.Info(ctx, "after create database tables")

	email := config.Global().ServerConfig.ManagementPortalInitUserEmail
	if email == nil || *email == "" {
		return errors.New("the first management portal user email is empty")
	}
	now := time.Now()

	managementPortalTenant := &entity.Tenant{
		Name:     "pingcap management portal",
		Alias:    "",
		Email:    *email,
		Country:  "CN",
		TimeZone: "0",
		Status:   "active",
		// use free trial to avoid send using tidb email
		Kind:          "internal",
		AcceptService: true,
		//Quotas:        quotas,
		Projects: nil,
	}
	managementPortalTenant.ID = entity.PingCAPTenantID
	if err := db.Create(managementPortalTenant).Error; err != nil {
		return err
	}

	adminRole := &entity.Role{
		TenantID: entity.PingCAPTenantID,
		Name:     "admin",
		Privileges: entity.Privileges{Privileges: []entity.Privilege{
			{
				Resource:  "*",
				Operation: "*",
			},
		}},
	}
	if err := db.Create(adminRole).Error; err != nil {
		return err
	}

	admin := &entity.User{
		Email:       *email,
		Status:      entity.UserStatusActive,
		InvitedAt:   &now,
		Job:         "sre",
		PhoneNumber: "",
		Roles:       []entity.Role{*adminRole},
		Role:        entity.UserRoleOwner,
	}
	if err := db.Create(admin).Error; err != nil {
		return err
	}

	adminRoleOnOrg := &entity.RoleBinding{
		TargetType: entity.RoleBindingTargetUser,
		TargetID:   admin.ID,
		ScopeType:  entity.RoleBindingScopeOrg,
		ScopeID:    entity.PingCAPTenantID,
		Role:       entity.RoleOrgOwner,
	}
	if err := db.Create(adminRoleOnOrg).Error; err != nil {
		return err
	}

	project := &entity.Project{
		TenantID: entity.PingCAPTenantID,
		Name:     config.DefaultProjectName,
		Users:    []entity.User{*admin},
	}
	err := project.Create(db)
	if err != nil {
		return err
	}

	adminRoleOnProject := &entity.RoleBinding{
		TargetType: entity.RoleBindingTargetUser,
		TargetID:   admin.ID,
		ScopeType:  entity.RoleBindingScopeProject,
		ScopeID:    project.ID,
		Role:       entity.RoleProjectOwner,
	}
	if err := db.Create(adminRoleOnProject).Error; err != nil {
		return err
	}

	tilog.Info(ctx, "after init empty database with data")
	return nil
}
