<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018-06-27
 * Time: 12:35
 */

namespace iBrand\Component\Discount\Test\Models;

use iBrand\Component\Discount\Contracts\DiscountSubjectContract;
use Illuminate\Database\Eloquent\Model;

class Order extends Model  implements DiscountSubjectContract
{
    protected $guarded=['id'];

    public function __construct(array $attributes = [])
    {
        $this->setTable(config('ibrand.app.database.prefix', 'ibrand_') . 'order');

        parent::__construct($attributes);
        $this->status = 0;
    }

    public function save(array $options = [])
    {
        $order = parent::save($options); // TODO: Change the autogenerated stub

        $this->items()->saveMany($this->getItems());

        $this->adjustments()->saveMany($this->getAdjustments());

        return $order;
    }

    public function items()
    {
        return $this->hasMany(OrderItem::class);
    }

    public function adjustments()
    {
        return $this->hasMany(Adjustment::class);
    }


    /**
     * get subject total amount.
     *
     * @return int
     */
    public function getSubjectTotal()
    {
         return $this->items_total;
    }

    /**
     * get subject count item.
     *
     * @return int
     */
    public function getSubjectCount()
    {
        return $this->count;
    }

    /**
     * get subject items.
     *
     * @return mixed
     */
    public function getItems()
    {
        return $this->items;
    }

    /**
     * get subject count.
     *
     * @return mixed
     */
    public function countItems()
    {
        return $this->items->count();
    }

    public function getAdjustments()
    {
        return $this->adjustments;
    }

    /**
     * @param $adjustment
     *
     * @return mixed
     */
    public function addAdjustment($adjustment)
    {
        if (!$this->hasAdjustment($adjustment)) {
            $this->adjustments->add($adjustment);
            $this->addToAdjustmentsTotal($adjustment);
        }
    }

    public function hasAdjustment(Adjustment $adjustment)
    {
        return $this->adjustments->contains(function ($value, $key) use ($adjustment) {
            if ($adjustment->order_item_id) {
                return $adjustment->origin_type == $value->origin_type
                    AND $adjustment->origin_id == $value->origin_id
                    AND $adjustment->order_item_id == $value->order_item_id;
            }
            return $adjustment->origin_type == $value->origin_type
                AND $adjustment->origin_id == $value->origin_id;
        });
    }

    protected function addToAdjustmentsTotal(Adjustment $adjustment)
    {
        $this->adjustments_total += $adjustment->amount;
        $this->recalculateTotal();
    }

    public function recalculateTotal()
    {
        $this->total = $this->items_total + $this->adjustments_total;

        if ($this->total < 0) {
            $this->total = 0;
        }
    }

    /**
     * get subject user.
     *
     * @return mixed
     */
    public function getSubjectUser()
    {
        // TODO: Implement getSubjectUser() method.
    }

    /**
     * get current total.
     *
     * @return mixed
     */
    public function getCurrentTotal()
    {
        return $this->total;
    }

    /**
     * get subject is paid.
     *
     * @return mixed
     */
    public function isPaid()
    {
        return $this->pay_status;
    }

    public function addItem(OrderItem $item)
    {
        if ($this->hasItem($item) AND !isset($item->item_meta['dynamic_sku'])) {
            return;
        }

        $this->items_total += $item->getTotal();
        $this->items->add($item);
        $this->recalculateTotal();
        $this->recalculateCount();
    }

    public function hasItem(OrderItem $item)
    {
        return $this->items->contains(function ($value, $key) use ($item) {
            return $item->item_id == $value->item_id AND $item->type = $value->type;
        });
    }

    protected function recalculateCount()
    {
        $this->count = $this->getTotalQuantity();
    }

    /**
     * {@inheritdoc}
     */
    public function getTotalQuantity()
    {
        $quantity = 0;

        foreach ($this->items as $item) {
            $quantity += $item->quantity;
        }

        return $quantity;
    }

    public function recalculateItemsTotal()
    {
        $items_total = 0;

        foreach ($this->items as $item) {
            $items_total += $item->total;
        }

        $this->items_total = $items_total;
        $this->recalculateTotal();
    }
}