<?php

namespace App\Packages\User\Models;

use App\Packages\Capsule\Models\Capsule;
use App\Packages\Capsule\Models\CapsuleComment;
use App\Packages\Core\Traits\RepositoryTrait;
use App\Packages\User\Models\User;
use App\Packages\v4\User\Notifications\TypesNotification;
use App\Packages\User\Repository\UserNotificationRepository;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Carbon;
use Ramsey\Uuid\Uuid;

/**
 * Class UserNotification
 * @package App\Packages\User\Models
 *
 * @property int $id
 * @property string $uuid
 * @property int $owner_id
 * @property int $user_id
 * @property int $type
 * @property boolean $is_seen
 * @property string $content
 * @property int $comment_id
 * @property int $capsule_id
 * @property int $friend_id
 * @property int $created_at_micro
 * @property string $hash
 *
 * @property string|Carbon $created_at
 * @property string|Carbon $updated_at
 *
 * @property-read User $owner
 * @property-read User $user
 * @property-read CapsuleComment $comment
 * @property-read Capsule $capsule
 *
 * @method static UserNotificationRepository repository()
 */
class UserNotification extends Model
{
	use RepositoryTrait;

	/** @var string */
	public static $repositoryClass = UserNotificationRepository::class;

	/** @var string */
	protected $table = 'table_user_notification';

    public static function boot()
    {
        parent::boot();
        static::creating(function ($model) {
            /** @var static $model */
            $model->uuid = Uuid::uuid4();
        });
    }

	/**
	 * @return mixed
	 */
	public function getTypeTitle()
	{
		return TypesNotification::$types[$this->type];
	}

	/**
	 * @return string
	 */
	public function getFormattedCreated()
	{
		return $this->created_at->format('Y-m-d H:i:s');
	}

    /**
     * @param $hash
     * @return mixed
     */
	public static function findByHash($hash)
    {
        return (new static())->query()
            ->where('hash', '=', $hash)
            ->first();
    }

	/**
	 * @param User $owner
	 * @param string $type
	 *
	 * @return UserNotification
	 */
	public static function storeNotification(User $owner, $type)
	{
		$notification = new UserNotification();
		$notification->owner_id = $owner->id;
		$notification->is_seen = 0;
		$notification->content = '';
		$notification->type = $type;
		$notification->created_at_micro = intMicroTime();

		return $notification;
	}

	/**
	 * @param Capsule $capsule
	 *
	 * @return $this
	 */
	public function setCapsule(Capsule $capsule)
	{
		$this->capsule_id = $capsule->id;

		return $this;
	}

	/**
	 * @param User $user
	 *
	 * @return $this
	 */
	public function setUser(User $user)
	{
		$this->user_id = $user->id;

		return $this;
	}

	/**
	 * @param CapsuleComment $comment
	 *
	 * @return $this
	 */
	public function setComment(CapsuleComment $comment)
	{
		$this->comment_id = $comment->id;

		return $this;
	}

    /**
     * @param bool $duplicate
     *
     * @return $this
     */
	public function persist($duplicate = false)
    {
        $hash = md5($this->owner_id . $this->type . $this->capsule_id  . $this->user_id . $this->comment_id);

        $notification = static::findByHash($hash);
        if ($duplicate || !$notification) {
            $this->hash = $hash;
            $this->save();
        }

        return $this;
    }

	/**
	 * @return HasOne
	 */
	public function owner()
	{
		return $this->hasOne(User::class, 'id', 'owner_id');
	}

	/**
	 * @return HasOne
	 */
	public function user()
	{
		return $this->hasOne(User::class, 'id', 'user_id');
	}

	/**
	 * @return HasOne
	 */
	public function comment()
	{
		return $this->hasOne(CapsuleComment::class, 'id', 'comment_id');
	}

	/**
	 * @return HasOne
	 */
	public function capsule()
	{
		return $this->hasOne(Capsule::class, 'id', 'capsule_id');
	}
}
