<?php

namespace App\Modules\UserTask\Services;

use App\Jobs\UserTaskJob;
use App\Modules\UserTask\Models\Task;
use App\Modules\UserTask\Models\UserRepeatTask;
use App\Modules\UserTask\Models\UserTask;
use Illuminate\Database\Eloquent\Collection;

class UserTaskService
{
    const add_trigger = 'add';
    const judge_trigger = 'judge';

    private $uid;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(int $uid)
    {
        $this->uid = $uid;
    }

    /**
     * 触发任务
     * @param string $type 任务类型
     * @param string $trigger_type 触发类型
     */
    public function trigger(string $type, string $trigger_type)
    {
        $model = $this->model($type);
        $tasks = Task::where('type', $type)->get();
        foreach ($tasks as $task) {
            $model->setTask($task);
            switch ($trigger_type) {
                case self::add_trigger:
                    $model->handleAddUserTask();
                    break;
                case self::judge_trigger:
                    $model->handleAddUserTask();
                    $model->handleUpToUserTask();
                    break;
            }
        }
    }

    /**
     * 领取任务奖励
     * @return int
     */
    public function getTaskReward(int $task_id)
    {
        $task = Task::find($task_id);
        $model = $this->model($task->type, $task);
        return $model->handleUserTaskReward();
    }

    /**
     * 获取任务model
     * @return SingleTask|ChargeTask|ReadTask
     */
    public function model(string $type, Task $task = null)
    {
        switch ($type) {
            case SingleTask::register:
            case SingleTask::bind_phone:
            case SingleTask::add_desk:
                return new SingleTask($this->uid, $task);
                break;
            case RepeatTask::charge:
                return new ChargeTask($this->uid, $task);
                break;
            case RepeatTask::read:
                return new ReadTask($this->uid, $task);
                break;
        }
    }

    /**
     * 添加用户任务队列
     * @param int $uid 
     * @param string $type 任务类型
     * @param string $trigger_type 触发类型
     */
    public static function addUserTaskQueue(int $uid, string $type, string $trigger_type)
    {
        $job = new UserTaskJob($uid, $type, $trigger_type);
        dispatch($job)->onConnection('rabbitmq')->onQueue('qapp_user_task_queue');
    }

    /**
     * 新手任务
     */
    public function findNewUserTaskList()
    {
        $tasks = $this->findTaskList(BaseTask::new_user_codes);
        $this->setUserTaskStatus($tasks, 'new');
        return $tasks;
    }

    /**
     * 用户每日任务
     */
    public function findDateUserTaskList()
    {
        $tasks = $this->findTaskList(BaseTask::date_codes);
        $this->setUserTaskStatus($tasks, 'date');
        return $tasks;
    }

    /**
     * 查找任务列表
     * @return Collection
     */
    private function findTaskList(array $codes)
    {
        return Task::whereIn('code', $codes)->where('is_enabled', 1)->get();
    }

    /**
     * 查找用户单次任务
     * @return Collection
     */
    private function findUserTasks(array $task_ids)
    {
        return UserTask::whereIn('task_id', $task_ids)->where('uid', $this->uid)->get();
    }

    /**
     * 查找用户每日任务
     * @return Collection
     */
    private function findUserDateTasks(array $task_ids)
    {
        $model = UserRepeatTask::model($this->uid);
        $date = date('Y-m-d');
        return  $model::whereIn('task_id', $task_ids)
            ->where('date', '>=', $date)
            ->where('uid', $this->uid)
            ->get();
    }

    /**
     * 设置用户任务状态标记
     */
    private function setUserTaskStatus(Collection $tasks, string $code_type)
    {
        $task_ids = $tasks->pluck('id')->all();
        if ($code_type == 'new') {
            $user_tasks = $this->findUserTasks($task_ids);
        } else if ($code_type == 'date') {
            $user_tasks = $this->findUserDateTasks($task_ids);
        } else {
            $user_tasks = collect();
        }
        $tasks->transform(function (Task $task) use ($user_tasks) {
            $user_task = $user_tasks->where('task_id', $task->id)->first();
            $task->status = $user_task ?  $user_task->status : 0;
            return $task;
        });
    }
}