<?php

namespace App\Models\Ecommerce\Product\Product\Concerns;

use App\Models\Common\Comment;
use App\Models\Ecommerce\Channel\Channel;
use App\Models\Ecommerce\Product\Brand\Brand;
use App\Models\Ecommerce\Product\Cart\Cart;
use App\Models\Ecommerce\Product\Category\Category;
use App\Models\Ecommerce\Product\Collection\Collection;
use App\Models\Ecommerce\Product\Inventory\Inventory;
use App\Models\Ecommerce\Product\Product\Product;
use App\Models\Ecommerce\Product\Property\ProductProperty;
use App\Models\Ecommerce\Product\Review\Review;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphToMany;

trait ProductRelationships
{
    /**
     * Product variations
     */
    public function variations(): HasMany
    {
        return $this->hasMany(Product::class, 'parent_id');
    }

    /**
+     * Parent
+     */
    public function parent(): BelongsTo
    {
        return $this->belongsTo(Product::class, 'parent_id');
    }

    /**
     * Related Channels
     */
    public function channels(): MorphToMany
    {
        return $this->morphedByMany(Channel::class, 'productable', 'product_has_relations');
    }

    /**
     * Firt channel
     */
    public function owner(): ?Channel
    {
        return $this->relationLoaded('channels')
                    ? $this->channels->first()
                    : $this->channels()->first();
    }

    /**
     * Related products (similar)
     */
    public function relatedProducts(): MorphToMany
    {
        return $this->morphedByMany(Product::class, 'productable', 'product_has_relations');
    }

    /**
     * Related categories
     */
    public function categories(): MorphToMany
    {
        return $this->morphedByMany(Category::class, 'productable', 'product_has_relations');
    }

    /**
     * Related Collections
     */
    public function collections(): MorphToMany
    {
        return $this->morphedByMany(Collection::class, 'productable', 'product_has_relations');
    }

    /**
     * Related Brand
     */
    public function brand(): BelongsTo
    {
        return $this->belongsTo(Brand::class, 'brand_id');
    }

    /**
     * Product Properties, same as attribtues
     *
     * (size, color, material, ..)
     */
    public function properties(): HasMany
    {
        return $this->hasMany(ProductProperty::class);
    }

    /**
     * Related inventories
     */
    public function inventories(): BelongsToMany
    {
        return $this->belongsToMany(Inventory::class)
            ->withPivot('stock');
    }

    /**
     * Carts
     */
    public function carts(): BelongsTo
    {
        return $this->belongsTo(Cart::class);
    }

    /**
     * Product's review
     */
    public function reviews(): HasMany
    {
        return $this->hasMany(Review::class);
    }

    /**
     * Product's comments
     */
    public function comments(): BelongsToMany
    {
        return $this->belongsToMany(Comment::class);
    }
}
