package models

import (
	"log"

	"git.apinb.com/bsm-sdk/core/types"
	"git.apinb.com/bsm-sdk/core/utils"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
)

// 初始化超级管理员用户
func InitRootUserData() {
	salt := utils.UUID()
	account := "root"
	password := "123456"
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password+salt), bcrypt.DefaultCost)
	if err != nil {
		log.Printf("初始化root密码加密失败: %v", err)
		return
	}

	var cnt int64
	DBService.Model(&MgtUser{}).Where("account=?", account).Count(&cnt)
	if cnt > 0 {
		return
	}

	admin := MgtUser{
		Std_IICUDS: types.Std_IICUDS{Identity: utils.UUID(), Status: 1},
		Name:       account,
		Account:    account,
		Phone:      "10000000000",
		Password:   string(hashedPassword),
		Email:      "root@apinb.com",
		Salt:       salt,
	}

	app := MgtApplication{
		Std_IICUDS:  types.Std_IICUDS{Identity: utils.UUID(), Status: 1},
		Workspace:   "DEF",
		Title:       "管理系统",
		Description: "管理系统",
	}

	adminRole := MgtRole{
		Std_IICUDS:  types.Std_IICUDS{Identity: utils.UUID(), Status: 1},
		Name:        "超级管理员",
		Description: "系统超级管理员，拥有所有权限",
	}

	if err := DBService.Transaction(func(tx *gorm.DB) error {
		// 1. 创建或获取应用
		if err := tx.Model(&MgtApplication{}).Where("workspace=?", app.Workspace).FirstOrCreate(&app).Error; err != nil {
			log.Printf("初始化应用异常: %v", err)
			return err
		}

		// 2. 创建管理员用户
		if err := tx.Model(&MgtUser{}).Where("account=?", admin.Account).FirstOrCreate(&admin).Error; err != nil {
			log.Printf("初始化用户异常: %v", err)
			return err
		}

		// 3. 创建管理员角色
		if err := tx.Model(&MgtRole{}).Where("name=?", adminRole.Name).FirstOrCreate(&adminRole).Error; err != nil {
			log.Printf("初始化角色异常: %v", err)
			return err
		}
		// 4. 默认权限：失败则内置 6 条管理菜单
		perms, errP := buildPermissions(tx, app.ID)
		if errP != nil {
			log.Printf("初始化权限异常: %v", errP)
			return errP
		}

		for _, seed := range perms {
			pmn := MgtPermission{
				Std_IICUDS: types.Std_IICUDS{Identity: utils.UUID(), Status: 1},
				Code:       seed.Code,
				Title:      seed.Title,
				MenuPath:   seed.MenuPath,
				Type:       seed.Type,
				SortKey:    seed.SortKey,
				Appid:      app.ID,
			}
			if err := tx.Where("app_id = ? AND code = ?", app.ID, seed.Code).FirstOrCreate(&pmn).Error; err != nil {
				log.Printf("初始化权限异常: %v", err)
				return err
			}
		}

		// 5. 关联应用-用户
		userAppLink := MgtLinkUserApp{AppId: app.ID, UserId: admin.ID}
		if err := tx.Where("app_id=? AND user_id=?", app.ID, admin.ID).FirstOrCreate(&userAppLink).Error; err != nil {
			log.Printf("初始化应用-用户的关联异常: %v", err)
			return err
		}

		// 6. 关联用户-角色
		userRoleLink := MgtLinkUserRole{UserId: admin.ID, RoleId: adminRole.ID}
		if err := tx.Where("user_id=? AND role_id=?", admin.ID, adminRole.ID).FirstOrCreate(&userRoleLink).Error; err != nil {
			log.Printf("初始化用户-角色的关联异常: %v", err)
			return err
		}

		// 7. 关联角色-应用
		roleAppLink := MgtLinkRoleApp{AppId: app.ID, RoleId: adminRole.ID}
		if err := tx.Where("app_id=? AND role_id=?", app.ID, adminRole.ID).FirstOrCreate(&roleAppLink).Error; err != nil {
			log.Printf("初始化角色-应用的关联异常: %v", err)
			return err
		}

		// 8. 关联角色-权限
		for _, pmn := range perms {
			rolePmnLink := MgtLinkRolePmn{
				RoleId: adminRole.ID,
				AppId:  app.ID,
				PmnId:  pmn.ID,
			}
			if err := tx.Where("role_id=? AND app_id=? AND pmn_id=?", adminRole.ID, app.ID, pmn.ID).FirstOrCreate(&rolePmnLink).Error; err != nil {
				log.Printf("初始化角色-权限的关联异常: %v", err)
				return err
			}

			// 9. 关联用户-权限
			userPmnLink := MgtLinkUserPmn{
				UserId: admin.ID,
				AppId:  app.ID,
				PmnId:  pmn.ID,
			}
			if err := tx.Where("user_id=? AND app_id=? AND pmn_id=?", admin.ID, app.ID, pmn.ID).FirstOrCreate(&userPmnLink).Error; err != nil {
				log.Printf("初始化用户-权限的关联异常: %v", err)
				return err
			}
		}

		return nil
	}); err != nil {
		log.Printf("初始化数据事务失败: %v", err)
		return
	}

	log.Printf("【初始化应用成功】%v:%v", app.Title, app.Workspace)
	log.Printf("【初始化用户成功】%v，请尽快修改默认密码", admin.Account)
	log.Printf("【初始化角色成功】%v", adminRole.Name)
}

func setupRegister() {
	var err error
	err = DBService.SetupJoinTable(&MgtUser{}, "Departments", &MgtLinkUserDpt{})
	if err != nil {
		log.Println(err)
	}
	err = DBService.SetupJoinTable(&MgtDepartment{}, "Users", &MgtLinkUserDpt{})
	if err != nil {
		log.Println(err)
	}

	err = DBService.SetupJoinTable(&MgtUser{}, "Roles", &MgtLinkUserRole{})
	if err != nil {
		log.Println(err)
	}
	err = DBService.SetupJoinTable(&MgtRole{}, "Users", &MgtLinkUserRole{})
	if err != nil {
		log.Println(err)
	}

	err = DBService.SetupJoinTable(&MgtUser{}, "Permissions", &MgtLinkUserPmn{})
	if err != nil {
		log.Println(err)
	}
	err = DBService.SetupJoinTable(&MgtPermission{}, "Users", &MgtLinkUserPmn{})
	if err != nil {
		log.Println(err)
	}
	err = DBService.SetupJoinTable(&MgtUser{}, "PmnApplication", &MgtLinkUserPmn{})
	if err != nil {
		log.Println(err)
	}
	err = DBService.SetupJoinTable(&MgtApplication{}, "UsersPmn", &MgtLinkUserPmn{})
	if err != nil {
		log.Println(err)
	}

	err = DBService.SetupJoinTable(&MgtUser{}, "Application", &MgtLinkUserApp{})
	if err != nil {
		log.Println(err)
	}
	err = DBService.SetupJoinTable(&MgtApplication{}, "Users", &MgtLinkUserApp{})
	if err != nil {
		log.Println(err)
	}

	err = DBService.SetupJoinTable(&MgtRole{}, "Permissions", &MgtLinkRolePmn{})
	if err != nil {
		log.Println(err)
	}
	err = DBService.SetupJoinTable(&MgtPermission{}, "Roles", &MgtLinkRolePmn{})
	if err != nil {
		log.Println(err)
	}
	err = DBService.SetupJoinTable(&MgtRole{}, "PmnApplication", &MgtLinkRolePmn{})
	if err != nil {
		log.Println(err)
	}
	err = DBService.SetupJoinTable(&MgtApplication{}, "RolesPmn", &MgtLinkRolePmn{})
	if err != nil {
		log.Println(err)
	}

	err = DBService.SetupJoinTable(&MgtRole{}, "Application", &MgtLinkRoleApp{})
	if err != nil {
		log.Println(err)
	}
	err = DBService.SetupJoinTable(&MgtApplication{}, "Roles", &MgtLinkRoleApp{})
	if err != nil {
		log.Println(err)
	}

	err = DBService.SetupJoinTable(&MgtDepartment{}, "Roles", &MgtLinkDptRole{})
	if err != nil {
		log.Println(err)
	}
	err = DBService.SetupJoinTable(&MgtRole{}, "Departments", &MgtLinkDptRole{})
	if err != nil {
		log.Println(err)
	}

	err = DBService.SetupJoinTable(&MgtDepartment{}, "Permissions", &MgtLinkDptPmn{})
	if err != nil {
		log.Println(err)
	}
	err = DBService.SetupJoinTable(&MgtPermission{}, "Departments", &MgtLinkDptPmn{})
	if err != nil {
		log.Println(err)
	}
	err = DBService.SetupJoinTable(&MgtDepartment{}, "PmnApplication", &MgtLinkDptPmn{})
	if err != nil {
		log.Println(err)
	}
	err = DBService.SetupJoinTable(&MgtApplication{}, "DepartmentsPmn", &MgtLinkDptPmn{})
	if err != nil {
		log.Println(err)
	}
}
