package service

import (
	"fmt"
	"github.com/linmadan/egglib-go/core/application"
	"github.com/linmadan/egglib-go/utils/tool_funs"
	"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/application/factory"
	"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/application/task/command"
	"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/application/task/query"
	"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain"
)

// 任务服务
type TaskService struct {
}

// 对任务进行抢单
func (taskService *TaskService) RobTask(robTaskCommand *command.RobTaskCommand) (interface{}, error) {
	if err := robTaskCommand.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 (taskService *TaskService) BidTask(bidTaskCommand *command.BidTaskCommand) (interface{}, error) {
	if err := bidTaskCommand.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 (taskService *TaskService) ChooseSuccessfulBidder(chooseSuccessfulBidderCommand *command.ChooseSuccessfulBidderCommand) (interface{}, error) {
	if err := chooseSuccessfulBidderCommand.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 (taskService *TaskService) ApplyCompleteTask(applyCompleteTaskCommand *command.ApplyCompleteTaskCommand) (interface{}, error) {
	if err := applyCompleteTaskCommand.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 (taskService *TaskService) ReleaseTask(releaseTaskCommand *command.ReleaseTaskCommand) (interface{}, error) {
	if err := releaseTaskCommand.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 (taskService *TaskService) OffTask(offTaskCommand *command.OffTaskCommand) (interface{}, error) {
	if err := offTaskCommand.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 (taskService *TaskService) AcceptanceTask(acceptanceTaskCommand *command.AcceptanceTaskCommand) (interface{}, error) {
	if err := acceptanceTaskCommand.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 (taskService *TaskService) CreateTask(createTaskCommand *command.CreateTaskCommand) (interface{}, error) {
	if err := createTaskCommand.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 employeeRepository domain.EmployeeRepository
	if value, err := factory.CreateEmployeeRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, err
	} else {
		employeeRepository = value
	}
	sponsor, err := employeeRepository.FindOne(map[string]interface{}{
		"uid": createTaskCommand.Sponsor,
	})
	if err != nil {
		return nil, err
	}
	if sponsor == nil {
		return nil, fmt.Errorf("无效的发布者")
	}
	var bidInfo *domain.BidInfo
	if createTaskCommand.TaskType == domain.TASK_TYPE_BID {
		bidInfo = &domain.BidInfo{
			BidStartTime: createTaskCommand.BidStartTime,
			BidEndTime:   createTaskCommand.BidEndTime,
		}
	} else {
		bidInfo = nil
	}
	newTask := &domain.Task{
		TaskStatus: domain.TASK_STATUS_UNRELEASED,
		CompanyId:  createTaskCommand.CompanyId,
		TaskName:   createTaskCommand.TaskName,
		TaskType:   createTaskCommand.TaskType,
		Sponsor:    sponsor.EmployeeInfo,
		ReferenceResource: &domain.ReferenceResource{
			ReferenceResourceType:  createTaskCommand.ReferenceResourceType,
			ReferenceResourceItems: createTaskCommand.ReferenceResourceItems,
		},
		CustomerValue:      createTaskCommand.CustomerValue,
		TaskNature:         createTaskCommand.TaskNature,
		SuMoney:            createTaskCommand.SuMoney,
		AcceptanceStandard: createTaskCommand.AcceptanceStandard,
		TaskDescription:    createTaskCommand.TaskDescription,
		TaskPictureUrls:    createTaskCommand.TaskPictureUrls,
		IsRewardTake:       createTaskCommand.IsRewardTake,
		BidInfo:            bidInfo,
	}
	var taskRepository domain.TaskRepository
	if value, err := factory.CreateTaskRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		taskRepository = value
	}
	if task, err := taskRepository.Save(newTask); 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 task, nil
	}
}

// 返回任务
func (taskService *TaskService) GetTask(getTaskQuery *query.GetTaskQuery) (interface{}, error) {
	if err := getTaskQuery.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 taskRepository domain.TaskRepository
	if value, err := factory.CreateTaskRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		taskRepository = value
	}
	task, err := taskRepository.FindOne(map[string]interface{}{"taskId": getTaskQuery.TaskId})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if task == nil {
		return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(getTaskQuery.TaskId)))
	} else {
		if err := transactionContext.CommitTransaction(); err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
		}
		return task, nil
	}
}

// 更新任务
func (taskService *TaskService) UpdateTask(updateTaskCommand *command.UpdateTaskCommand) (interface{}, error) {
	if err := updateTaskCommand.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 taskRepository domain.TaskRepository
	if value, err := factory.CreateTaskRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		taskRepository = value
	}
	task, err := taskRepository.FindOne(map[string]interface{}{"taskId": updateTaskCommand.TaskId})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if task == nil {
		return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(updateTaskCommand.TaskId)))
	}
	if err := task.Update(tool_funs.SimpleStructToMap(updateTaskCommand)); err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	if task, err := taskRepository.Save(task); 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 task, nil
	}
}

// 移除任务
func (taskService *TaskService) RemoveTask(removeTaskCommand *command.RemoveTaskCommand) (interface{}, error) {
	if err := removeTaskCommand.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 taskRepository domain.TaskRepository
	if value, err := factory.CreateTaskRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		taskRepository = value
	}
	task, err := taskRepository.FindOne(map[string]interface{}{"taskId": removeTaskCommand.TaskId})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if task == nil {
		return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeTaskCommand.TaskId)))
	}
	if task, err := taskRepository.Remove(task); 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 task, nil
	}
}

// 返回任务列表
func (taskService *TaskService) ListTask(listTaskQuery *query.ListTaskQuery) (interface{}, error) {
	if err := listTaskQuery.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 taskRepository domain.TaskRepository
	if value, err := factory.CreateTaskRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		taskRepository = value
	}
	if count, tasks, err := taskRepository.Find(tool_funs.SimpleStructToMap(listTaskQuery)); 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,
			"tasks": tasks,
		}, nil
	}
}

func NewTaskService(options map[string]interface{}) *TaskService {
	newTaskService := &TaskService{}
	return newTaskService
}