<?php

namespace App\Modules\Bookings;

use App\Modules\Stock\StockPurchaseOrderItem;
use App\Models\ValidationModel;
use App\Models\User;
use App\Modules\Stock\Stock;

class Build extends ValidationModel
{
    use \Venturecraft\Revisionable\RevisionableTrait;

    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'builds';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['related_id', 'related_type', 'stock_id', 'quantity', 'status', 'name', 'price', 'group_id'];

    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    protected $appends = ['cost'];

    /**
     * Array of validation rules.
     *
     * @var  array
     */
    protected static $rules = [
        'related_id'   => 'required',
        'related_type' => 'required',
        'quantity'     => 'required',
    ];

    /**
     * The model's attributes.
     *
     * @var array
     */
    protected $attributes = [
            'status'    => 'planning',
        ];

    /**
     * The relations to eager load on every query.
     *
     * @var array
     */
    protected $with = ['stock', 'planned_components', 'ordered_components'];

    /**
     * The "booting" method of the model.
     *
     * @return void
     */
    public static function boot()
    {
        parent::boot();

        // When a transaction is created we want to
        // update the created_by field
        static::creating(function ($model) {
            $model->created_by = getAuthUserId();
        });
    }

    /**
     * Retrieves the cost amount for the build.
     *
     * @return float
     */
    public function getCostAttribute()
    {
        if ($this->status != 'planning') {
            $cost = 0;
            foreach ($this->stock->composite_items as $item) {
                if ($latest_order = StockPurchaseOrderItem::where('stock_id', $item->id)->orderBy('created_at', 'DESC')->first()) {
                    $cost += $latest_order->unit_cost * $item->pivot->quantity;
                }
            }
        } else {
            $cost = 0;
            foreach ($this->planned_components as $item) {
                if ($latest_order = StockPurchaseOrderItem::where('stock_id', $item->id)->orderBy('created_at', 'DESC')->first()) {
                    $cost += $latest_order->unit_cost * $item->pivot->quantity;
                }
            }
        }

        return $cost;
    }

    /**
     * Returns the user who added the part.
     *
     * @return \User
     */
    public function creator()
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    /**
     * Returns the user who added the part.
     *
     * @return App\Modules\Bookings\Task
     */
    public function related()
    {
        return $this->morphTo();
    }

    /**
     * Returns the stock item for the part.
     *
     * @return App\Modules\Stock\StockItem
     */
    public function stock()
    {
        return $this->belongsTo(Stock::class, 'stock_id')->withTrashed();
    }

    /**
     * Relationship: query builder to return all the composite items for this part.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function ordered_components()
    {
        return $this->belongsToMany(Stock::class, 'build_ordered_components', 'build_id', 'stock_id')->withTimestamps()->withPivot('quantity');
    }

    /**
     * Relationship: query builder to return all the composite items for this part.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function planned_components()
    {
        return $this->belongsToMany(Stock::class, 'build_planned_components', 'build_id', 'stock_id')->withTimestamps()->withPivot('quantity');
    }

    /**
     * Check if the build planned components are the same than in the original template.
     *
     * @param  App/Modules/Bookings/Build 		$build
     * @param  array 							$items
     *
     * @return bool
     */
    public static function samePlannedComponents(Build $build, $items)
    {
        $original_components = $build->planned_components()->get();

        if (count($original_components) != count($items)) {
            return false;
        }

        foreach ($original_components as $item) {
            if (! isset($items[$item->id])) {
                return false;
            }

            if ($item->pivot->quantity != $items[$item->id]['quantity']) {
                return false;
            }
        }

        return true;
    }
}
