package user

import (
	"github.com/tiptok/gocomm/common"
	"github.com/tiptok/gocomm/pkg/log"
	"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/application/factory"
	"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/domain"
	"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol"
	protocolx "gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol/user"
)

type UserService struct {
}

func (svr *UserService) CreateUser(header *protocol.RequestHeader, request *protocolx.CreateUserRequest) (rsp interface{}, err error) {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
	)
	rsp = &protocolx.CreateUserResponse{}
	if err = request.ValidateCommand(); err != nil {
		err = protocol.NewCustomMessage(2, err.Error())
	}
	if err = transactionContext.StartTransaction(); err != nil {
		log.Error(err)
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	newUser := &domain.User{
		Name:    request.Name,
		Address: request.Address,
		Phone:   request.Phone,
		Passwd:  request.Passwd,
		Roles:   request.Roles,
		IsAdmin: request.IsAdmin,
	}

	var UserRepository, _ = factory.CreateUserRepository(transactionContext)
	if m, err := UserRepository.Save(newUser); err != nil {
		return nil, err
	} else {
		rsp = m
	}
	err = transactionContext.CommitTransaction()
	return
}

func (svr *UserService) UpdateUser(header *protocol.RequestHeader, request *protocolx.UpdateUserRequest) (rsp interface{}, err error) {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
	)
	rsp = &protocolx.UpdateUserResponse{}
	if err = request.ValidateCommand(); err != nil {
		err = protocol.NewCustomMessage(2, err.Error())
	}
	if err = transactionContext.StartTransaction(); err != nil {
		log.Error(err)
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	var UserRepository, _ = factory.CreateUserRepository(transactionContext)
	var user *domain.User
	if user, err = UserRepository.FindOne(common.ObjectToMap(request)); err != nil {
		return
	}
	if err = user.Update(common.ObjectToMap(request)); err != nil {
		return
	}
	if user, err = UserRepository.Save(user); err != nil {
		return
	}
	err = transactionContext.CommitTransaction()
	return
}

func (svr *UserService) GetUser(header *protocol.RequestHeader, request *protocolx.GetUserRequest) (rsp interface{}, err error) {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
	)
	rsp = &protocolx.GetUserResponse{}
	if err = request.ValidateCommand(); err != nil {
		err = protocol.NewCustomMessage(2, err.Error())
	}
	if err = transactionContext.StartTransaction(); err != nil {
		log.Error(err)
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	var UserRepository, _ = factory.CreateUserRepository(transactionContext)
	var user *domain.User
	if user, err = UserRepository.FindOne(common.ObjectToMap(request)); err != nil {
		return
	}
	rsp = user
	err = transactionContext.CommitTransaction()
	return
}

func (svr *UserService) DeleteUser(header *protocol.RequestHeader, request *protocolx.DeleteUserRequest) (rsp interface{}, err error) {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
	)
	rsp = &protocolx.DeleteUserResponse{}
	if err = request.ValidateCommand(); err != nil {
		err = protocol.NewCustomMessage(2, err.Error())
	}
	if err = transactionContext.StartTransaction(); err != nil {
		log.Error(err)
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	var UserRepository, _ = factory.CreateUserRepository(transactionContext)
	var user *domain.User
	if user, err = UserRepository.FindOne(common.ObjectToMap(request)); err != nil {
		return
	}
	if user, err = UserRepository.Remove(user); err != nil {
		return
	}
	rsp = user
	err = transactionContext.CommitTransaction()
	return
}

func (svr *UserService) ListUser(header *protocol.RequestHeader, request *protocolx.ListUserRequest) (rsp interface{}, err error) {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
	)
	rsp = &protocolx.ListUserResponse{}
	if err = request.ValidateCommand(); err != nil {
		err = protocol.NewCustomMessage(2, err.Error())
	}
	if err = transactionContext.StartTransaction(); err != nil {
		log.Error(err)
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	var UserRepository, _ = factory.CreateUserRepository(transactionContext)
	var user []*domain.User
	var total int64
	if total, user, err = UserRepository.Find(common.ObjectToMap(request)); err != nil {
		return
	}
	rsp = map[string]interface{}{
		"total": total,
		"list":  user,
	}
	err = transactionContext.CommitTransaction()
	return
}

func NewUserService(options map[string]interface{}) *UserService {
	svr := &UserService{}
	return svr
}