<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;

/**
 * @property Collection<Supplier> suppliers
 */
class ProfitCenter extends BaseAuditable
{
    protected $guarded = ['id', 'created_at', '	updated_at'];

    protected $appends = ['fullAddress', 'primaryPhone'];

    use SoftDeletes;

    /**
     * The users that belong to the ProfitCenter.
     */
    public function users(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'profit_center_users')->withTimestamps();
    }

    /**
     * The suppliers that belong to the ProfitCenter.
     */
    public function suppliers(): BelongsToMany
    {
        return $this->belongsToMany(Supplier::class)->withTimestamps();
    }

    public function contact(): MorphMany
    {
        return $this->morphMany(Contact::class, 'contactable');
    }

    public function address(): MorphMany
    {
        return $this->morphMany(Address::class, 'attachable');
    }

    public function attachment(): MorphMany
    {
        return $this->morphMany(Attachment::class, 'attachable');
    }

    public function syncContactRelations(array $contactIds): bool
    {
        return $this->syncMorph(Contact::class, 'contactable', $contactIds);
    }

    public function syncRelations(array $relIds, $relType): bool
    {
        return $this->syncMorph($relType, 'attachable', $relIds);
    }

    public function syncMorph($class, $classFunctionName, $ids = []): bool
    {
        if (! class_exists($class)) {
            $class = __NAMESPACE__.'\\'.$class;
            if (! class_exists($class)) {
                return false;
            }
        }
        $f = new \ReflectionClass($class);
        $relationFunctionName = lcfirst($f->getShortName());
        if (method_exists($this, $relationFunctionName)) {
            $associated = $this->$relationFunctionName()->pluck('id')->toArray();
            $needToRemove = array_diff($associated, $ids);
            $needToAdd = array_diff($ids, $associated);
            if (count($needToRemove) > 0) {
                foreach ($needToRemove as $id) {
                    $item = $class::find($id);
                    $item->$classFunctionName()->dissociate($this);
                    $item->save();
                }
            }
            if (count($needToAdd) > 0) {
                foreach ($needToAdd as $id) {
                    $item = $class::find($id);
                    $item->$classFunctionName()->associate($this);
                    $item->save();
                }
            }

            return true;
        }

        return false;
    }

    public function getFullAddressAttribute(): string
    {
        return "{$this->postCode} {$this->city} {$this->street}";

        return $this->postCode.' '.$this->city.' '.$this->street;
    }

    public function getPrimaryPhoneAttribute(): ?string
    {
        if (! $this->mobil) {
            if ($this->phone) {
                return $this->phone;
            } else {
                return null;
            }
        }

        return $this->mobil;
    }

    /**
     * The Product that belong to the ProfitCenter.
     */
    public function favorites(): BelongsToMany
    {
        return $this->belongsToMany(Product::class, 'profit_center_favorites')->withTimestamps();
    }

    public function favoritesBySupplier($supplierId): BelongsToMany
    {
        return $this->belongsToMany(Product::class, 'profit_center_favorites')->where('supplier_id', '=', $supplierId);
    }
}
