package service

import (
	"fmt"
	"github.com/linmadan/egglib-go/core/application"
	"github.com/linmadan/egglib-go/utils/tool_funs"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/factory"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/role/command"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/role/query"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/utils"
	"time"
)

// 角色
type RoleService struct {
}

// 分配角色给多个用户
func (roleService *RoleService) AssginRoleToUsers(assginRoleToUsersCommand *command.AssginRoleToUsersCommand) (interface{}, error) {
	if err := assginRoleToUsersCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return nil, nil
}

// 创建角色
func (roleService *RoleService) CreateRole(createRoleCommand *command.CreateRoleCommand) (interface{}, error) {
	if err := createRoleCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	_, org, err := factory.FastPgOrg(transactionContext, createRoleCommand.OrgId)
	if err != nil {
		return nil, err
	}
	roleRepository, _, err := factory.FastPgRole(transactionContext, 0)
	if existsRole, e := roleRepository.FindOne(map[string]interface{}{"companyId": org.CompanyId, "orgId": org.OrgId, "roleName": createRoleCommand.RoleName}); e == nil && existsRole != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, "该角色在当前组织机构已经存在")
	}

	createRoleService, err := factory.CreatePgCreateRoleService(map[string]interface{}{
		"transactionContext": transactionContext,
	})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	newRole := &domain.Role{
		RoleName:    createRoleCommand.RoleName,
		Desc:        createRoleCommand.Desc,
		OrgId:       org.OrgId,
		CompanyId:   org.CompanyId,
		AccessMenus: []int64{},
		RoleType:    domain.RoleTypeNormal,
		Ext: &domain.Ext{
			OrgName: org.OrgName,
		},
		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
	}
	role, err := createRoleService.CreateRole(nil, newRole)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return role, nil
}

// 返回角色
func (roleService *RoleService) GetRole(getRoleQuery *query.GetRoleQuery) (interface{}, error) {
	if err := getRoleQuery.ValidateQuery(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var roleRepository domain.RoleRepository
	if value, err := factory.CreateRoleRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		roleRepository = value
	}
	role, err := roleRepository.FindOne(map[string]interface{}{"roleId": getRoleQuery.RoleId, "includeDeleted": true})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if role == nil {
		return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(getRoleQuery.RoleId)))
	} else {
		if err := transactionContext.CommitTransaction(); err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
		}
		return role, nil
	}
}

// 获取角色菜单
func (roleService *RoleService) GetRoleAccessMenus(getRoleAccessMenusQuery *query.GetRoleAccessMenusQuery) (interface{}, error) {
	if err := getRoleAccessMenusQuery.ValidateQuery(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return nil, nil
}

// 获取角色相关联的用户
func (roleService *RoleService) GetRoleRelatedUsers(getRoleRelatedUsersQuery *query.GetRoleRelatedUsersQuery) (interface{}, error) {
	if err := getRoleRelatedUsersQuery.ValidateQuery(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return nil, nil
}

// 返回角色列表
func (roleService *RoleService) ListRole(listRoleQuery *query.ListRoleQuery) (interface{}, error) {
	if err := listRoleQuery.ValidateQuery(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var roleRepository domain.RoleRepository
	if value, err := factory.CreateRoleRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		roleRepository = value
	}
	queryOptions := utils.ObjectToMap(listRoleQuery)
	queryOptions["includeDeleted"] = false
	if count, roles, err := roleRepository.Find(queryOptions); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		if err := transactionContext.CommitTransaction(); err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
		}
		return map[string]interface{}{
			"count": count,
			"roles": roles,
		}, nil
	}
}

// 移除角色
func (roleService *RoleService) RemoveRole(removeRoleCommand *command.RemoveRoleCommand) (interface{}, error) {
	if err := removeRoleCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var roleRepository domain.RoleRepository
	if value, err := factory.CreateRoleRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		roleRepository = value
	}
	role, err := roleRepository.FindOne(map[string]interface{}{"roleId": removeRoleCommand.RoleId})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if role == nil {
		return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeRoleCommand.RoleId)))
	}
	role.DeletedAt = time.Now()
	if role, err := roleRepository.Remove(role); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		if err := transactionContext.CommitTransaction(); err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
		}
		return role, nil
	}
}

// 取消用户分配的角色
func (roleService *RoleService) UnAssginRoleToUsers(unAssginRoleToUsersCommand *command.UnAssginRoleToUsersCommand) (interface{}, error) {
	if err := unAssginRoleToUsersCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return nil, nil
}

// 更新角色
func (roleService *RoleService) UpdateRole(updateRoleCommand *command.UpdateRoleCommand) (interface{}, error) {
	if err := updateRoleCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	roleRepository, role, err := factory.FastPgRole(transactionContext, updateRoleCommand.RoleId)
	if err != nil {
		return nil, err
	}
	if existsRole, e := roleRepository.FindOne(map[string]interface{}{"companyId": role.CompanyId, "orgId": role.OrgId, "roleName": updateRoleCommand.RoleName}); e == nil && existsRole != nil && existsRole.RoleId != role.RoleId {
		return nil, application.ThrowError(application.BUSINESS_ERROR, "该角色在当前组织机构已经存在")
	}

	if err := role.Update(tool_funs.SimpleStructToMap(updateRoleCommand)); err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	if _, org, _ := factory.FastPgOrg(transactionContext, role.OrgId); org != nil {
		role.Ext.OrgName = org.OrgName
	}
	if role, err := roleRepository.Save(role); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		if err := transactionContext.CommitTransaction(); err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
		}
		return role, nil
	}
}

// 设置角色菜单
func (roleService *RoleService) UpdateRoleAccessMenus(updateRoleAccessMenusCommand *command.UpdateRoleAccessMenusCommand) (interface{}, error) {
	if err := updateRoleAccessMenusCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return nil, nil
}

func NewRoleService(options map[string]interface{}) *RoleService {
	newRoleService := &RoleService{}
	return newRoleService
}