package user

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

type UserService struct{}

func (us *UserService) ListUsers(listUserQuery *query.ListUserQuery) (interface{}, 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()
	}()
	userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
	count, list, err := userRepo.Find(map[string]interface{}{
		"companyId": listUserQuery.CompanyId,
		"name":      listUserQuery.Name,
		"status":    domain.UserStatusEnable,
	})
	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 tool_funs.SimpleWrapGridMap(int64(count), list), nil
}

func (us *UserService) ListByDepartment(in *query.ListByDepartmentQuery) (interface{}, error) {
	transactionContext, err := factory.ValidateStartTransaction(in)
	if err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
	positionRepo := factory.CreatePositionRepository(map[string]interface{}{"transactionContext": transactionContext})

	inMap := tool_funs.SimpleStructToMap(in)
	if in.DepartmentId == 0 {
		delete(inMap, "departmentId") // 删除部门ID字段
	}
	count, list, err := userRepo.Find(inMap)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	parentIds := make([]int64, 0) // 上级ID
	positionIds := make([]int, 0) // 职位ID
	for i := range list {
		if list[i].ParentId > 0 {
			parentIds = append(parentIds, list[i].ParentId)
		}

		pList := list[i].PositionId
		for i2 := range pList {
			if pList[i2] > 0 {
				positionIds = append(positionIds, pList[i2])
			}
		}
	}

	// 获取上级
	parentMap := map[int64]*domain.User{}
	if len(parentIds) > 0 {
		_, parentList, err := userRepo.Find(map[string]interface{}{"ids": parentIds})
		if err != nil {
			return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
		}
		for i := range parentList {
			parentMap[parentList[i].Id] = parentList[i]
		}
	}

	// 获取职位
	positionMap := map[int64]*domain.Position{}
	if len(positionIds) > 0 {
		_, positionList, err := positionRepo.Find(map[string]interface{}{"ids": positionIds})
		if err != nil {
			return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
		}
		for i := range positionList {
			positionMap[positionList[i].Id] = positionList[i]
		}
	}

	adapters := make([]*adapter.UserResp, 0)
	for i := range list {
		adp := &adapter.UserResp{
			User: list[i],
		}
		// 上级名称
		if v, ok := parentMap[list[i].ParentId]; ok {
			adp.ParentName = v.Name
		}
		// 职位名称数组
		adp.PositionNames = make([]string, 0)
		pList := list[i].PositionId
		for i2 := range pList {
			if v2, ok := positionMap[int64(pList[i2])]; ok {
				adp.PositionNames = append(adp.PositionNames, v2.Name)
			}
		}
		adapters = append(adapters, adp)
	}

	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return tool_funs.SimpleWrapGridMap(int64(count), adapters), nil
}

// EditParentUser 保存上级
func (us *UserService) EditParentUser(in *command.EditParentCommand) error {
	transactionContext, err := factory.ValidateStartTransaction(in)
	if err != nil {
		return err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	hrbp, err := service.GetHRBP(transactionContext, in.CompanyId, in.OperatorId)
	if err != nil {
		return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if hrbp != 1 {
		return application.ThrowError(application.BUSINESS_ERROR, "HRBP权限的员工才能操作")
	}

	userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
	user, err := userRepo.FindOne(map[string]interface{}{"id": in.Id})
	if err != nil {
		return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	if in.ParentId != 0 {
		// 上级ID是否存在
		_, err = userRepo.FindOne(map[string]interface{}{"id": in.ParentId})
		if err != nil {
			return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
		}
	}
	user.ParentId = in.ParentId

	if _, err = userRepo.Update(user); err != nil {
		return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	if err := transactionContext.CommitTransaction(); err != nil {
		return application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return nil
}

func (us *UserService) ImportParentUser(in *command.ImportParentUserCommand) (interface{}, error) {
	transactionContext, err := factory.ValidateStartTransaction(in)
	if err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	hrbp, err := service.GetHRBP(transactionContext, in.CompanyId, in.OperatorId)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if hrbp != 1 {
		return nil, application.ThrowError(application.BUSINESS_ERROR, "HRBP权限的员工才能操作")
	}
	userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})

	userMap := map[string]*domain.User{}
	accounts := make([]string, 0) // 全部账号数组(查询一次)
	for i := range in.Data {
		v := in.Data[i]
		if len(v.Phone) == 0 || len(v.ParentPhone) == 0 {
			continue
		}
		accounts = append(accounts, v.Phone)
		accounts = append(accounts, v.ParentPhone)
	}
	if len(accounts) > 0 {
		if _, users, err := userRepo.Find(map[string]interface{}{"accounts": accounts, "companyId": in.CompanyId}); err != nil {
			return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
		} else {
			for i := range users {
				userMap[users[i].Account] = users[i]
			}
		}
	}

	for i := range in.Data {
		v := in.Data[i]
		if len(v.Phone) == 0 || len(v.ParentPhone) == 0 {
			continue
		}
		if vCurrentUser, ok := userMap[v.Phone]; ok {
			if vParentUser, ok := userMap[v.ParentPhone]; ok {
				vCurrentUser.ParentId = vParentUser.Id

				// 更新上级数据
				if _, err := userRepo.Update(vCurrentUser); 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 nil, nil
}