<?php

namespace Mtc\Plugins\MembersMessaging\Classes\Traits;

use Mtc\Plugins\MembersMessaging\Classes\Message;
use Mtc\Plugins\MembersMessaging\Classes\MessagesRead;
use Mtc\Plugins\MembersMessaging\Classes\Participant;
use Mtc\Plugins\MembersMessaging\Classes\Thread;

trait Messagable
{
    /**
     * Message relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     *
     * @codeCoverageIgnore
     */
    public function messages()
    {
        return $this->hasMany(Message::class);
    }

    /**
     * Participants relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     *
     * @codeCoverageIgnore
     */
    public function participants()
    {
        return $this->hasMany(Participant::class);
    }

    /**
     * Thread relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\belongsToMany
     *
     * @codeCoverageIgnore
     */
    public function threads()
    {
        return $this->belongsToMany(
            Models::classname(Thread::class),
            Models::table('participants'),
            'user_id',
            'thread_id',
        );
    }

    /**
     * Returns the new messages count for user.
     *
     * @return int
     */
    public function newThreadsCount()
    {
        return $this->threadsWithNewMessages()->count();
    }

    /**
     * Returns all threads with new messages.
     *
     * @return \Illuminate\Database\Eloquent\Relations\belongsToMany
     */
    public function threadsWithNewMessages()
    {
        return $this->threads()
            ->where(function ($q): void {
                $q->whereNull(Models::table('participants').'.last_read');
                $q->orWhere(
                    Models::table('threads').'.updated_at',
                    '>',
                    $this->getConnection()->raw(
                        $this->getConnection()->getTablePrefix().Models::table('participants').'.last_read',
                    ),
                );
            })
            ->get();
    }
}
