package system

import (
	"context"

	"kra/internal/biz/system"
	"kra/internal/data/model"

	"github.com/google/uuid"
	"github.com/pkg/errors"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
)

const initOrderUser = initOrderAuthority + 1

type initUser struct{}

func NewInitUser() system.SubInitializer {
	return &initUser{}
}

func (i *initUser) MigrateTable(ctx context.Context) (context.Context, error) {
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		return ctx, system.ErrMissingDBContext
	}
	return ctx, db.AutoMigrate(&model.SysUser{})
}

func (i *initUser) TableCreated(ctx context.Context) bool {
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		return false
	}
	return db.Migrator().HasTable(&model.SysUser{})
}

func (i *initUser) InitializerName() string {
	return model.TableNameSysUser
}

func (i *initUser) InitializeData(ctx context.Context) (next context.Context, err error) {
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		return ctx, system.ErrMissingDBContext
	}

	ap := ctx.Value("adminPassword")
	apStr, ok := ap.(string)
	if !ok {
		apStr = "123456"
	}

	password := bcryptHash(apStr)
	adminPassword := bcryptHash(apStr)

	entities := []model.SysUser{
		{
			UUID:        uuid.New().String(),
			Username:    "admin",
			Password:    adminPassword,
			NickName:    "超级管理员",
			HeaderImg:   "https://qmplusimg.henrongyi.top/1576554439myAvatar.png",
			AuthorityID: 888,
			Phone:       "17611111111",
			Email:       "333333333@qq.com",
		},
		{
			UUID:        uuid.New().String(),
			Username:    "a303176530",
			Password:    password,
			NickName:    "用户1",
			HeaderImg:   "https://qmplusimg.henrongyi.top/1572075907logo.png",
			AuthorityID: 9528,
			Phone:       "17611111111",
			Email:       "333333333@qq.com",
		},
	}
	if err = db.Create(&entities).Error; err != nil {
		return ctx, errors.Wrap(err, model.TableNameSysUser+"表数据初始化失败!")
	}
	next = context.WithValue(ctx, i.InitializerName(), entities)

	// 获取权限数据
	authorities, ok := ctx.Value(model.TableNameSysAuthority).([]model.SysAuthority)
	if !ok {
		return next, errors.Wrap(system.ErrMissingDependentContext, "创建 [用户-权限] 关联失败, 未找到权限表初始化数据")
	}

	// 为admin用户分配所有权限
	for _, auth := range authorities {
		if err = db.Exec("INSERT INTO sys_user_authority (sys_user_id, sys_authority_authority_id) VALUES (?, ?)", entities[0].ID, auth.AuthorityID).Error; err != nil {
			return next, errors.Wrap(err, "为admin用户分配权限失败")
		}
	}

	// 为普通用户分配第一个权限
	if err = db.Exec("INSERT INTO sys_user_authority (sys_user_id, sys_authority_authority_id) VALUES (?, ?)", entities[1].ID, authorities[0].AuthorityID).Error; err != nil {
		return next, errors.Wrap(err, "为普通用户分配权限失败")
	}

	return next, nil
}

func (i *initUser) DataInserted(ctx context.Context) bool {
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		return false
	}
	var count int64
	if err := db.Model(&model.SysUser{}).Where("username = ?", "a303176530").Count(&count).Error; err != nil {
		return false
	}
	return count > 0
}

// bcryptHash 使用bcrypt对密码进行加密
func bcryptHash(password string) string {
	bytes, _ := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	return string(bytes)
}
