package system

import (
	"spaceofcheng/services/models"
	"spaceofcheng/services/models/model"
	"spaceofcheng/services/utils"
	"strconv"
	"strings"
	"time"

	"github.com/go-xorm/xorm"
)

// RoleDAO 菜单
type RoleDAO struct {
	ctx *utils.Context
	db  *xorm.Session
}

// NewRoleDAO New Inst
func NewRoleDAO(ctx *utils.Context) *RoleDAO {
	return &RoleDAO{
		ctx: ctx,
		db:  ctx.DB,
	}
}

// GetRoleCount 获取角色总数
func (m *RoleDAO) GetRoleCount(caseids, name, caseid string) (int, error) {
	var roles []model.SysRole
	dao := m.db.Where("status>" + strconv.Itoa(models.STATUS_DEL)).And("case_id in ('" + strings.Replace(caseids, ",", "','", -1) + "')")
	if name != "" {
		dao.And("role_name like '%" + name + "%'")
	}
	if caseid != "" {
		dao.And("case_id =?", caseid)
	}
	err := dao.Find(&roles)
	return len(roles), err
}

// GetRoleList 根据案场获取角色
func (m *RoleDAO) GetRoleList(caseids, name, caseid string, page int, pageSize int) ([]model.SysRole, error) {
	var roles []model.SysRole
	dao := m.db.Where("status>" + strconv.Itoa(models.STATUS_DEL)).And("case_id in ('" + strings.Replace(caseids, ",", "','", -1) + "')")
	if name != "" {
		dao.And("role_name like '%" + name + "%'")
	}
	if caseid != "" {
		dao.And("case_id =?", caseid)
	}
	err := dao.Limit(pageSize, (page-1)*pageSize).Desc("create_date").Find(&roles)
	return roles, err
}

// Role 角色
type Role struct {
	model.SysRole `xorm:"extends"`
	RoleMenu      []model.SysMenu
}

// GetRoleByID 根据ID获取角色
func (m *RoleDAO) GetRoleByID(roleid string) (*model.SysRole, error) {
	var roles []model.SysRole
	sql := `select * from sys_role where role_id='` + roleid + `' and status>` + strconv.Itoa(models.STATUS_DEL)
	err := m.db.Sql(sql).Find(&roles)
	if err != nil {
		return nil, err
	}
	if len(roles) > 0 {
		return &roles[0], err
	}
	return nil, nil
}

// GetRoleMenuByRoleID 根据角色ID获取角色对应菜单
func (m *RoleDAO) GetRoleMenuByRoleID(roleid string) ([]model.SysMenu, error) {
	var menus []model.SysMenu
	sql := `select a.* from sys_menu a inner join sys_role_menu b on a.menu_id=b.menu_id where b.role_id='` + roleid + `'`
	err := m.db.Sql(sql).Find(&menus)
	return menus, err
}

// AddRole 新增角色
func (m *RoleDAO) AddRole(role model.SysRole) (*model.SysRole, error) {
	role.RoleId = utils.GetGUID()
	role.Status = models.STATUS_NORMAL
	role.CreateDate = time.Now()
	_, err := m.db.Insert(role)
	return &role, err
}

// UpdateRole 修改角色
func (m *RoleDAO) UpdateRole(Role model.SysRole) error {
	var cols = []string{
		"role_name",
		"remark",
	}
	_, err := m.db.Cols(cols...).Where("role_id=?", Role.RoleId).Update(Role)
	return err
}

// DeleteRole 刪除角色
func (m *RoleDAO) DeleteRole(roleid string) error {
	var Role = model.SysRole{
		RoleId: roleid,
		Status: models.STATUS_DEL,
	}
	var cols = []string{
		"status",
	}
	_, err := m.db.Cols(cols...).Where("role_id=?", Role.RoleId).Update(Role)
	return err
}

// DelRoleMenu 删除角色对应的菜单
func (m *RoleDAO) DelRoleMenu(roleid string) error {
	sql := "delete from sys_role_menu where role_id='" + roleid + "'"
	_, err := m.db.Exec(sql)
	return err
}

// SaveRoleMenu 保存角色对应的菜单
func (m *RoleDAO) SaveRoleMenu(roleid, menuids string) error {
	sql := `insert into sys_role_menu(role_id,menu_id) select DISTINCT '` + roleid + `', a.menu_id from sys_menu a left join sys_menu b on find_in_set(b.menu_id,a.father_ids) where (b.menu_id in ('` + strings.Replace(menuids, ",", "','", -1) + `') or a.menu_id in ('` + strings.Replace(menuids, ",", "','", -1) + `')) and a.status> ` + strconv.Itoa(models.STATUS_DEL)
	_, err := m.db.Exec(sql)
	return err
}

// DelUserMenusByRole 批量删除处理用户对应菜单信息
func (m *RoleDAO) DelUserMenusByRole(roleid string) error {
	sql := "delete a from sys_user_menu a inner join sys_user_role b on a.user_id=b.user_id where b.role_id='" + roleid + "'"
	_, err := m.db.Exec(sql)
	return err
}

// SaveUserMenusByRole 批量保存用户对应菜单信息
func (m *RoleDAO) SaveUserMenus(roleid string) error {
	sql := `insert into sys_user_menu (user_id,menu_id)
	select DISTINCT c.user_id,a.menu_id from sys_menu a 
	inner join sys_role_menu b on a.menu_id = b.menu_id
	inner join sys_user_role c on b.role_id = c.role_id
	where c.user_id in (select user_id from sys_user_role where role_id='` + roleid + `')`
	_, err := m.db.Exec(sql)
	return err
}
