<?php

namespace App\Models\Shop;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

use Spatie\MediaLibrary\HasMedia;
use Rinvex\Categories\Traits\Categorizable;
use Rinvex\Tags\Traits\Taggable;
use Kirschbaum\PowerJoins\PowerJoins;
use Fico7489\Laravel\EloquentJoin\Traits\EloquentJoin;
use Wildside\Userstamps\Userstamps;
use Staudenmeir\EloquentHasManyDeep\HasRelationships;

use App\Traits\Model\HasComments;
use App\Traits\Model\Imageable;

use App\Models\Botanic\Variety;
use App\Models\Botanic\Specie;

class Article extends Model implements HasMedia
{
    use Categorizable, EloquentJoin, HasComments, HasRelationships, Imageable, Powerjoins, Taggable, SoftDeletes, UserStamps;

    protected $guarded = ['id'];
    protected $table = 'shop_articles';

    public function article_nature()
    {
        return $this->belongsTo(ArticleNature::class);
    }

    public function invoiceItems()
    {
        return $this->hasMany(InvoiceItem::class);
    }

    public function offers()
    {
        return $this->hasMany(Offer::class);
    }

    public function price_lists()
    {
        return $this->hasManyDeep(
            PriceList::class,
            [Offer::class, Tariff::class],
            ['article_id', 'id'],
            ['id', 'tariff_id'],
        );
    }

    public function prices()
    {
        return $this->hasManyDeep(
            PriceListValue::class,
            [Offer::class, Tariff::class, PriceList::class],
            ['article_id', 'id', 'tariff_id'],
            ['id', 'tariff_id', 'id'],
        );
    }

    public function product()
    {
        return $this->morphTo();
    }

    public function siblings()
    {
        return $this->hasMany(Article::class, 'name', 'name');
    }

    public function tags()
    {
        return $this->morphToMany(Tag::class, 'taggable');
    }

    public function tariffs()
    {
        return $this->hasManyThrough(Tariff::class, Offer::class, 'article_id', 'id', 'id', 'tariff_id');
        // return $this->belongsToMany(Tariff::class, Offer::$table, 'id', 'id', 'tariff_id', 'tariff_id');
    }

    public function scopeByArticle($query, $id)
    {
        return $query->where($this->table . '.id', $id);
    }

    public function scopeByAutocomplete($query, $str)
    {
        return $query->where($this->table . '.name', 'LIKE', "%${str}%");
    }

    public function scopeSearch($query, $str)
    {
        return $query->where($this->table . '.name', 'LIKE', "%${str}%");
    }

    public function scopeByArticleNature($query, $id)
    {
        return $query->where($this->table . '.article_nature_id', $id);
    }

    public function scopeByArticleNatures($query, $ids)
    {
        return $query->whereIn($this->table . '.article_nature_id', $ids);
    }

    public function scopeByCategories($query, $categories_id)
    {
        return $categories_id ? $query->whereHas('categories', function ($query) use ($categories_id) {
            $query->whereIn('id', $categories_id);
        }) : $query;
    }

    public function scopeByCategoryParent($query, $category_id)
    {
        $category = Category::find($category_id);
        return $category_id ? $query->whereHas('categories', function ($query) use ($category) {
            $query->where('_lft', '>=', $category->_lft)->where('_rgt', '<=', $category->_rgt);
        }) : $query;
    }

    public function scopeByCategory($query, $category_id)
    {
        return $category_id ? $query->whereHas('categories', function ($query) use ($category_id) {
            $query->where('id', $category_id);
        }) : $query;
    }

    public function scopeBotanic($query)
    {
        return $query->whereIn($this->table . '.product_type', [Variety::class, Specie::class]);
    }

    public function scopeMerchandise($query)
    {
        return $query->byProduct(Merchandise::class);
    }

    public function scopeByProduct($query, $model)
    {
        return $query->where($this->table . '.product_type', $model);
    }

    public function scopeByProductId($query, $model_id)
    {
        return $query->where($this->table . '.product_id', $model_id);
    }

    public function scopeByTag($query, $tag_id)
    {
        return $tag_id ? $query->whereHas('tags', function ($query) use ($tag_id) {
            $query->where('id', $tag_id);
        }) : $query;
    }

    public function scopeByTags($query, $tags)
    {
        return $tags ? $query->whereHas('tags', function ($query) use ($tags) {
            $query->whereIn('id', $tags);
        }) : $query;
    }

    public function scopeByTagsSelected($query, $tags)
    {
        return $tags ? $query->whereHas('tags', function ($query) use ($tags) {
            foreach ($tags as $tag) {
                $query->where('id', $tag);
            }
        }) : $query;
    }

    public function scopeWithOffers($query)
    {
        return $query->has('offers');
    }

    public function scopeWithAvailableOffers($query, $sale_channel_id = false)
    {
        return $query->whereHas('offers', function ($query) use ($sale_channel_id) {
            $query->active()->byStockAvailable()->bySaleChannel($sale_channel_id);
        });
    }

    public function scopeVisible($query)
    {
        return $query->where($this->table . '.visible', 1);
    }

    public function scopeHomepage($query)
    {
        return $query->where($this->table . '.homepage', 1);
    }
}
