package common

import (
	"crypto/rand"
	"database/sql"
	"dbweb/core"
	"dbweb/lib/model"
	"dbweb/modules/common/recordview"
	"strings"

	"github.com/linlexing/dbx/data"
	"github.com/linlexing/dbx/ddb"
)

//BatchAddUser 批量增加用户
type BatchAddUser struct{}

func init() {
	core.RegisterFun("batchadduser", new(BatchAddUser), "_layout/blank")
}

//Get 业务
func (u *BatchAddUser) Get(p *core.ElementHandleArgs) {
	callParams := recordview.GetCallParam(p)
	fromEle := core.LoadElement(p.DB, callParams.FromElement)
	p.More["FromElement"] = fromEle
	roles := []string{}
	SQL := "select name,dept,visible from role where dept in(?) order by dept,name"
	depts := []string{}
	for i := range p.User.Dept.Code {
		depts = append(depts, p.User.Dept.Code[:len(p.User.Dept.Code)-i])
	}
	SQL, param, err := data.In(SQL, depts)
	if err != nil {
		core.LOG.Panic(err)
	}
	rows, err := p.DB.Query(SQL, param...)
	if err != nil {
		core.LOG.Panic(err)
	}
	defer rows.Close()
	for rows.Next() {
		var vName string
		var vDept sql.NullString
		var vVisible sql.NullString
		if err = rows.Scan(&vName, &vDept, &vVisible); err != nil {
			core.LOG.Panic(err)
		}
		role := &DBRole{
			Name:    vName,
			Dept:    vDept.String,
			Visible: vVisible.String,
		}
		if role.IsShow(p.User) {
			roles = append(roles, role.Name)
		}
	}
	p.More["Roles"] = roles
	p.HTML()
}

//Post 业务
func (u *BatchAddUser) Post(p *core.ElementHandleArgs) {
	var message string
	dept := p.User.Dept.Code
	userStr := p.Req.PostFormValue("user")
	roles := p.Req.PostForm["chkrole"]
	users := strings.Split(userStr, "\n")
	//过滤所有空行
	var tUser []string
	for _, v := range users {
		user := strings.Fields(v)
		if len(user) != 0 {
			tUser = append(tUser, v)
		}
	}
	//控制添加数量在1~1000条
	if len(tUser) == 0 || len(tUser) > 1000 {
		message = "添加数量不符合要求，请控制在1~1000条！"
		p.Render.JSON(200, message)
		return
	}
	//判断添加数据是否符合要求
	for _, v := range tUser {
		user := strings.Fields(v)
		if len(user) != 2 {
			message = "有异常数据"
			p.Render.JSON(200, message)
			return
		}
	}
	//执行插入操作，添加事务
	//有问题 待修改
	if err := ddb.RunAtTx(p.DB, func(tx ddb.Txer) (err error) {
		md, err := core.NewModel(tx, modelUserName)
		if err != nil {
			core.LOG.Panic(err)
		}
		for _, v := range tUser {
			var userName, passWord string
			user := strings.Fields(v)
			userName = user[0]
			passWord = user[1]
			if err := insertUser(userName, passWord, dept, roles, md); err != nil {
				return err
			}
		}
		return err
	}); err != nil {
		message = "未完成, 可能用户名已存在！"
		p.Render.JSON(200, message)
		return
	}
	message = "添加成功"
	p.Render.JSON(200, message)
}

//添加用户
func insertUser(userName, passWord, Dept string, roles []string, md *model.Model) error {
	salt := make([]byte, 16)
	if _, err := rand.Read(salt); err != nil {
		core.LOG.Panic(err)
	}
	pwd, err := BuildUserPassword(passWord, salt)
	if err != nil {
		core.LOG.Panic(err)
	}
	var modelUserRoles []modelUserRole
	for _, role := range roles {
		mrole := modelUserRole{
			UserName: userName,
			RoleName: role,
		}
		modelUserRoles = append(modelUserRoles, mrole)
	}
	//insert
	err = md.Insert(modelUser{
		Name:     userName,
		Salt:     salt,
		Password: pwd,
		Dept:     Dept,
		Roles:    modelUserRoles,
	})
	return err
}
