<?php

namespace App\Modules\Bookings;

use App\Modules\Stock\StockTransaction;
use Exception;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Mail;
use App\Seraph\Services\GlobalMailerService;

class PartReceived
{
    /**
     * The part that was updated.
     *
     * @var \App\Modules\Bookings\Part
     */
    protected $part;

    /**
     * Subscribe to events.
     *
     * @param  mixed $events
     *
     * @return null
     */
    public function subscribe($events)
    {
        $events->listen('PartReceived', 'App\Modules\Bookings\PartReceived@fire');
    }

    /**
     * Fire the event.
     *
     * @param  \App\Modules\Bookings\Part $part
     *
     * @return bool
     */
    public function fire(Part $part, \App\Modules\Stock\Stock $stock, $quantity)
    {
        $this->part = $part;

        $this->createTransaction($stock, $quantity);
        $this->updateRelatedStatus();

        return $this->notifyUser($stock, $quantity);
    }

    /**
     * Send an email to the user to let them know the part was received.
     *
     * @return bool
     */
    protected function notifyUser(\App\Modules\Stock\Stock $stock, $quantity)
    {
        if ($this->part->related) {
            $send_to = $this->getUserToNotifyEmail();

            if ($send_to) {
                $part = $this->part;
                GlobalMailerService::send('emails.alerts.received_part_notification', ['part' => $part, 'stock' => $stock, 'quantity' => $quantity], function ($message) use ($part, $stock, $quantity, $send_to) {
                    // Configure the email options
                    $message->to($send_to)->subject('Received '.$stock->name.' for task '.$part->related_id);
                });
            }
        }
    }

    /**
     * Create a stock transaction that will
     * automatically update the stock.
     *
     * @return bool
     */
    protected function createTransaction(\App\Modules\Stock\Stock $stock, $quantity)
    {
        $transaction = StockTransaction::create([
            'stock_id'     => $stock->id,
            'related_type' => $this->part->related_type,
            'related_id'   => $this->part->related_id,
            'quantity'     => -$quantity,
        ]);

        if (! $transaction->exists) {
            throw new Exception('Failed to create stock transaction, '.json_encode($transaction->errors->all()));
        }

        return true;
    }

    /**
     * If the part is related to an order, it changes the status
     * of the order from "On Order" to "Delivered".
     *
     * @return bool
     */
    protected function updateRelatedStatus()
    {
        if ($this->part->related_type != 'task') {
            return;
        }

        $task = Task::findOrFail($this->part->related_id);
        $order_ready = $task->type == 'order' &&
                       $task->parts()->where('quantity_on_order', '>', 0)->count() == 0;
//                       $task->parts()->has('composite_items.quantity', '>', 0)->count() == 0;
		// 	Junaid 26/01/2017 changed above line from below to try and fix issue 33 https://git.computerassistance.co.uk/seraph/seraph3/issues/33
		//	$task->parts()->has('composite_items.quantity_on_order', '>', 0)->count() == 0;
        if ($order_ready) {
            $task->update(['status_id' => '16']);
        }
    }

    /**
     * Get the email of the user the "Part Received" notification has to be sent to.
     *
     * @return string | false
     */
    protected function getUserToNotifyEmail()
    {
        if ($this->part->related->user && $this->part->related->user->email) {
            return $this->part->related->user->email;
        }

        if ($this->part->related->type == 'order' && $this->part->related->creator && $this->part->related->creator->email) {
            return $this->part->related->creator->email;
        }

        return false;
    }
}
