package service

import (
	"github.com/linmadan/egglib-go/core/application"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/auth/adapter"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/auth/command"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/constant"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
)

type AuthService struct {
}

// Login PC端登录
func (service *AuthService) Login(loginCommand *command.LoginCommand) (interface{}, error) {
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if errStart := transactionContext.StartTransaction(); errStart != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, errStart.Error())
	}
	defer func() {
		_ = transactionContext.RollbackTransaction()
	}()
	//统一用户中心登录
	authCodeReply, err := factory.UCenterApi().AuthCode(loginCommand.Code)
	if err != nil || !authCodeReply.IsOk() {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "统一用户中心认证失败")
	}
	//用户权限校验
	userAuthReply, err := factory.BusinessAdminApi().GetUserAuth(authCodeReply.Data.MUid, loginCommand.PlatformId)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "用户鉴权失败")
	}
	if !userAuthReply.IsOk() {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, userAuthReply.Message())
	}
	//获取公司数据
	companyRepository := factory.CreateCompanyRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	})
	company, err := companyRepository.FindOne(map[string]interface{}{
		"id": authCodeReply.Data.CompanyId,
	})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取公司数据失败")
	}
	userRepository := factory.CreateUserRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	})
	user, err := userRepository.FindOne(map[string]interface{}{
		"id":        authCodeReply.Data.MUid,
		"companyId": company.Id,
	})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取用户数据失败")
	}
	if user.Status != domain.UserStatusEnable {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "用户被禁用")
	}
	userAuth := &domain.UserAuth{
		UserId:      user.Id,
		CompanyId:   user.CompanyId,
		CompanyName: company.Name,
		Phone:       user.Account,
		PlatformId:  loginCommand.PlatformId,
		Name:        user.Name,
		AdminType:   user.AdminType,
	}
	accessToken, err := userAuth.CreateAccessToken()
	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 map[string]interface{}{
		"access": map[string]interface{}{
			"accessToken": accessToken,
			"expiresIn":   domain.JWTExpiresSecond,
		},
	}, nil
}

// 员工绩效 手机端登录,来源于能力展示app
func (service *AuthService) MobileLogin(param *command.MobileLoginCommand) (map[string]interface{}, error) {
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if errStart := transactionContext.StartTransaction(); errStart != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, errStart.Error())
	}
	defer func() {
		_ = transactionContext.RollbackTransaction()
	}()
	// 统一用户中心登录
	authCodeReply, err := factory.UCenterApi().AppAuthCode(param.Credentials, param.Cuid, param.Cid)
	if err != nil || !authCodeReply.IsOk() {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "统一用户中心认证失败")
	}
	// 用户权限校验
	// 登录平台ID,28-绩效管理后台  29-员工绩效
	userAuthReply, err := factory.BusinessAdminApi().GetUserAuth(int64(param.Muid), constant.IdPlatformUser)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "用户鉴权失败")
	}
	if !userAuthReply.IsOk() {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, userAuthReply.Message())
	}
	//获取公司数据
	companyRepository := factory.CreateCompanyRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	})
	company, err := companyRepository.FindOne(map[string]interface{}{
		"id": param.Cid,
	})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取公司数据失败")
	}
	userRepository := factory.CreateUserRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	})
	user, err := userRepository.FindOne(map[string]interface{}{
		"id":        param.Muid,
		"companyId": company.Id,
	})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取用户数据失败")
	}
	if user.Status != domain.UserStatusEnable {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "用户被禁用")
	}
	userAuth := &domain.UserAuth{
		UserId:      user.Id,
		CompanyId:   user.CompanyId,
		CompanyName: company.Name,
		Phone:       user.Account,
		PlatformId:  constant.IdPlatformUser,
		Name:        user.Name,
		AdminType:   user.AdminType,
	}
	accessToken, err := userAuth.CreateAccessToken()
	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())
	}
	result := map[string]interface{}{
		"access": map[string]interface{}{
			"accessToken": accessToken,
			"expiresIn":   domain.JWTExpiresSecond,
		},
	}
	return result, nil
}

// 获取我的
func (service *AuthService) MeInfo(param *command.GetMeInfo) (map[string]interface{}, error) {

	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if errStart := transactionContext.StartTransaction(); errStart != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, errStart.Error())
	}
	defer func() {
		_ = transactionContext.RollbackTransaction()
	}()
	userRepository := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
	companyRepository := factory.CreateCompanyRepository(map[string]interface{}{"transactionContext": transactionContext})
	roleRepo := factory.CreateRoleRepository(map[string]interface{}{"transactionContext": transactionContext})
	roleUserRepo := factory.CreateRoleUserRepository(map[string]interface{}{"transactionContext": transactionContext})
	userData, err := userRepository.FindOne(map[string]interface{}{
		"id": param.UserId,
	})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取员工数据"+err.Error())
	}
	_, parentUser, err := userRepository.Find(map[string]interface{}{
		"parentId": userData.Id,
		"limit":    1,
	})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取员工数据"+err.Error())
	}
	companyData, err := companyRepository.FindOne(map[string]interface{}{
		"id": param.CompanyId,
	})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取公司数据"+err.Error())
	}
	_, roleList, err := roleRepo.Find(map[string]interface{}{"type": domain.RoleTypeSystem, "companyId": param.CompanyId})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取角色信息列表"+err.Error())
	}
	_, userRoleList, err := roleUserRepo.Find(map[string]interface{}{"companyId": param.CompanyId, "userId": param.UserId})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取用户的角色信息列表"+err.Error())
	}
	// 拥有HRBP权限
	isHrbp := false
loop:
	for _, v := range userRoleList {
		for _, v2 := range roleList {
			if v.RoleId == v2.Id {
				isHrbp = true
				break loop
			}
		}
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	info := adapter.MeInfo{
		UserId:      userData.Id,
		CompanyId:   companyData.Id,
		CompanyName: companyData.Name,
		Phone:       userData.Account,
		Name:        userData.Name,
		IsHrbp:      isHrbp,
		IsParent:    false,
	}
	if len(parentUser) > 0 {
		info.IsParent = true
	}
	return map[string]interface{}{
		"user": info,
	}, nil
}