<?php

namespace App\Modules\Gamification;

use Illuminate\Support\Facades\Log;
use App\Facades\DBconfig;

class TaskObserver
{
    protected $excluded = ['sale_lead', 'orders', 'rma'];

    // Define all the methods, but leave blank
    public function create($model)
    {
    }
    public function save($model)
    {
    }

    /**
     * Define all the logic that should happen when a task is saved.
     *
     * @param  \App\Modules\Bookings\Task $model
     *
     * @return void
     */
    public function saving($model)
    {
        // Stop if the module is disabled
        if (! DBconfig::get('gamification.enabled')) {
            return true;
        }

        // Ignore excluded task types
        if (array_search($model->type, $this->excluded) !== false) {
            return true;
        }

        if ($model->isDirty('completed') && $model->completed == 1) {
            $this->addPoints($model);
        } elseif ($model->isDirty('completed') && $model->completed == 0) {
            $this->revertTransactions($model);
        } elseif ($model->completed == 1 && ($model->isDirty('time_spent') || $model->isDirty('labour') || $model->isDirty('onsite_start') || $model->isDirty('onsite_end'))) {
            $this->revertTransactions($model);
            $this->addPoints($model);
        }
    }

    /**
     * Define the logic that happens when a task is deleted.
     *
     * @param  \App\Modules\Bookings\Task $model
     *
     * @return void
     */
    public function deleted($model)
    {
        // Stop if the module is disabled
        if (! DBconfig::get('gamification.enabled')) {
            return true;
        }

        $this->revertTransactions($model);
    }

    //------------------------------------------
    //
    //	Private helper methods below ------vvvvv
    //

    protected function addPoints($model)
    {
        if ($model->assigned_to) {
            $transaction = PointsTransaction::create([
                'identifier' => 'task',
                'user_id'    => $model->assigned_to,
                'action'     => 'add',
                'amount'     => $model->points,
                'task_id'    => $model->id,
                'created_by' => getAuthUserId(),
            ]);

            if (! $transaction->exists) {
                Log::error('Failed to create a points transaction.', $model->toArray());

                return false;
            }

            // Add the points to the user account
            $transaction->user->increment('points', $transaction->amount);
        }

        return true;
    }

    protected function revertTransactions($model)
    {
        $transactions = PointsTransaction::query()->where('task_id', $model->id)->get();

        foreach ($transactions as $transaction) {
            if ($transaction->action == 'add') {
                // Remove the points from the user account
                $transaction->user->decrement('points', $transaction->amount);
            } elseif ($transaction->action == 'substract') {
                // Add the points back to the user account
                $transaction->user->increment('points', $transaction->amount);
            }

            // Delete the transaction
            $transaction->delete();
        }

        return true;
    }
}
