package service

import (
	"strconv"

	"github.com/linmadan/egglib-go/core/application"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/application/web/roles/command"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/application/web/roles/dto"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/application/web/roles/query"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/infrastructure/service_gateway/allied_creation_user"
)

// roles
type RolesService struct {
}

// 创建role
func (rolesService *RolesService) RoleAdd(roleAddCommand *command.RoleAddCommand) (interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		roleAddCommand.Operator)
	result, err := creationUserGateway.RoleCreate(allied_creation_user.ReqRoleCreate{
		RoleName: roleAddCommand.RoleName,
		Desc:     roleAddCommand.Desc,
	})
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	data := struct {
		RoleId string `json:"roleId"`
		command.RoleAddCommand
	}{
		RoleId:         strconv.Itoa(int(result.RoleID)),
		RoleAddCommand: *roleAddCommand,
	}
	return data, err
}

// 编辑role
func (rolesService *RolesService) RoleEdit(roleUpdateCommand *command.RoleUpdateCommand) (interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		roleUpdateCommand.Operator)
	roleId, _ := strconv.Atoi(roleUpdateCommand.RoleId)
	_, err := creationUserGateway.RoleUpdate(allied_creation_user.ReqRoleUpdate{
		RoleId:   int64(roleId),
		RoleName: roleUpdateCommand.RoleName,
		Desc:     roleUpdateCommand.Desc,
	})
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return roleUpdateCommand, err
}

// 返单个角色
func (rolesService *RolesService) RoleGet(roleGetQuery *query.RoleGetQuery) (interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		roleGetQuery.Operator)
	roleId, _ := strconv.Atoi(roleGetQuery.RoleId)
	roleData, err := creationUserGateway.RoleGet(allied_creation_user.ReqRoleGet{
		RoleId: int64(roleId),
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	accessMenus, err := creationUserGateway.RoleGetAccessMenus(allied_creation_user.ReqRoleGetAccessMenus{
		RoleId: int64(roleId),
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	relatedUser, err := creationUserGateway.RoleRelatedUser(allied_creation_user.ReqRoleGetRelatedUser{
		RoleId: int64(roleId),
		OrgIds: roleGetQuery.Operator.OrgIds,
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	result := map[string]interface{}{
		"role":  roleData,
		"menus": accessMenus.Menus,
		"users": relatedUser.RoleUser,
	}
	return result, nil
}

// 返回role列表
func (rolesService *RolesService) RoleList(roleListQuery *query.RoleListQuery) (int64, interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		roleListQuery.Operator)
	roleList, err := creationUserGateway.RoleSearch(allied_creation_user.ReqRoleSearch{
		Offset:   (roleListQuery.PageNumber - 1) * roleListQuery.PageSize,
		Limit:    roleListQuery.PageSize,
		OrgName:  roleListQuery.OrgName,
		RoleName: roleListQuery.RoleName,
		InOrgIds: roleListQuery.Operator.OrgIds,
	})
	if err != nil {
		return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	result := []dto.RoleItem{}
	for _, v := range roleList.Roles {
		item := dto.RoleItem{
			RoleId:   strconv.Itoa(int(v.RoleID)),
			OrgId:    strconv.Itoa(int(v.OrgID)),
			RoleName: v.RoleName,
			Describe: v.Desc,
			OrgName:  v.Ext.OrgName,
			RoleType: v.RoleType,
			Ext:      v.Ext,
		}
		if int64(v.OrgID) == roleListQuery.Operator.OrgId {
			item.AuthFlag = 1
		}
		result = append(result, item)
	}
	var cnt int64 = roleList.Count
	return cnt, result, nil
}

// 编辑角色关联权限菜单的前置准备数据
func (rolesService *RolesService) RoleMenuBeforeEdit(roleMenuBeforeEditQuery *query.RoleMenuBeforeEditQuery) (interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		roleMenuBeforeEditQuery.Operator)
	roleId, _ := strconv.Atoi(roleMenuBeforeEditQuery.RoleId)
	roles, err := creationUserGateway.RoleSearch(allied_creation_user.ReqRoleSearch{
		OrgId:    roleMenuBeforeEditQuery.Operator.OrgId,
		Limit:    999,
		RoleType: 1,
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}

	menus, err := creationUserGateway.RoleGetAccessMenus(allied_creation_user.ReqRoleGetAccessMenus{
		RoleId: int64(roleId),
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	result := map[string]interface{}{
		"roles": roles.Roles,
		"menus": menus.Menus,
	}
	return result, nil
}

// 编辑角色关联用户的前置准备数据
func (rolesService *RolesService) RoleUserBeforeEdit(roleUserBeforeEditQuery *query.RoleUserBeforeEditQuery) (interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		roleUserBeforeEditQuery.Operator)
	roleId, _ := strconv.Atoi(roleUserBeforeEditQuery.RoleId)
	roles, err := creationUserGateway.RoleSearch(allied_creation_user.ReqRoleSearch{
		OrgId:    roleUserBeforeEditQuery.Operator.OrgId,
		Limit:    999,
		RoleType: 1,
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	orgs, err := creationUserGateway.OrgGetSubDepartment(allied_creation_user.ReqOrgGetSubDepartment{
		OrgId: roleUserBeforeEditQuery.Operator.OrgId,
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	result := map[string]interface{}{
		"orgs":  orgs.Orgs,
		"roles": roles.Roles,
	}
	// 有传入角色ID才返回关联角色用户数据
	if roleId > 0 {
		relatedUser, err := creationUserGateway.RoleGetRelatedUser(allied_creation_user.ReqRoleGetRelatedUser{
			RoleId: int64(roleId),
			OrgId:  roleUserBeforeEditQuery.Operator.OrgId,
		})

		if err != nil {
			return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
		}
		result["notInRoleUser"] = relatedUser.NotInRoleUser
		result["roleUser"] = relatedUser.RoleUser
	}

	return result, nil
}

// 角色编辑关联菜单权限
func (rolesService *RolesService) RoleMenuEdit(roleMenuEditCommand *command.RoleMenuEditCommand) (interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		roleMenuEditCommand.Operator)
	roleId, _ := strconv.Atoi(roleMenuEditCommand.RoleId)
	var menuIds []int64
	for _, v := range roleMenuEditCommand.MenuId {
		id, err := strconv.Atoi(v)
		if err == nil {
			menuIds = append(menuIds, int64(id))
		}
	}
	_, err := creationUserGateway.RoleSetAccessMenus(allied_creation_user.ReqRoleSetAccessMenus{
		RoleId:      int64(roleId),
		AccessMenus: menuIds,
	})
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return roleMenuEditCommand, err
}

// 移除role
func (rolesService *RolesService) RoleRemove(roleRemoveCommand *command.RoleRemoveCommand) (interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		roleRemoveCommand.Operator)

	var roleIds []int64
	for _, v := range roleRemoveCommand.RoleIds {
		id, err := strconv.Atoi(v)
		if err == nil {
			roleIds = append(roleIds, int64(id))
		}
	}
	_, err := creationUserGateway.RoleBatchRemove(allied_creation_user.ReqRoleBatchRemove{
		RoleIds: roleIds,
	})
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return roleRemoveCommand, err
}

// 角色添加关联用户
func (rolesService *RolesService) RoleUserAdd(roleUserAddCommand *command.RoleUserAddCommand) (interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		roleUserAddCommand.Operator)
	roleId, _ := strconv.Atoi(roleUserAddCommand.RoleId)
	var userIds []int64
	for _, v := range roleUserAddCommand.UserId {
		id, err := strconv.Atoi(v)
		if err == nil {
			userIds = append(userIds, int64(id))
		}
	}
	_, err := creationUserGateway.RoleAssign(allied_creation_user.ReqRoleAssign{
		RoleId:  int64(roleId),
		UserIds: userIds,
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	return roleUserAddCommand, err
}

// 角色添加关联用户
func (rolesService *RolesService) RoleUserDelete(roleUserDeleteCommand *command.RoleUserDeleteCommand) (interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		roleUserDeleteCommand.Operator)
	roleId, _ := strconv.Atoi(roleUserDeleteCommand.RoleId)
	var userIds []int64
	for _, v := range roleUserDeleteCommand.UserId {
		id, err := strconv.Atoi(v)
		if err == nil {
			userIds = append(userIds, int64(id))
		}
	}
	_, err := creationUserGateway.RoleUnassign(allied_creation_user.ReqRoleUnassign{
		RoleId:  int64(roleId),
		UserIds: userIds,
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	return roleUserDeleteCommand, err
}

// 角色下关联用户的数据
func (rolesService *RolesService) RoleUserInfo(roleUserInfoQuery *query.RoleUserInfoQuery) (interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		roleUserInfoQuery.Operator)
	relatedUser, err := creationUserGateway.RoleGetRelatedUser(allied_creation_user.ReqRoleGetRelatedUser{
		RoleId: roleUserInfoQuery.RoleId,
		OrgId:  roleUserInfoQuery.Operator.OrgId,
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	var result = make(map[string]interface{})
	result["notInRoleUser"] = relatedUser.NotInRoleUser
	result["roleUser"] = relatedUser.RoleUser
	return result, nil
}

func NewRolesService(options map[string]interface{}) *RolesService {
	newRolesService := &RolesService{}
	return newRolesService
}