<?php

namespace Mtc\Plugins\MembersMessaging\Classes;

use App\Casts\OptionalEncrypted;
use Illuminate\Database\Eloquent\Model as Eloquent;
use Mtc\Core\Admin\User;
use Mtc\Modules\Members\Classes\Auth;
use Mtc\Modules\Members\Models\Member;
use Mtc\Plugins\ContentReports\Classes\Reports;

class Message extends Eloquent
{
    public $humandate;

    protected $appends = [
        'humandate',
    ];

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'messenger_messages';

    /**
     * The relationships that should be touched on save.
     *
     * @var array
     */
    protected $touches = ['thread'];

    /**
     * The attributes that can be set with Mass Assignment.
     *
     * @var array
     */
    protected $fillable = [
        'id',
        'member_id',
        'thread_id',
        'text',
        'comment',
        'satisfactory',
        'admin',
        'private',
    ];

    protected $casts = [
        'text' => OptionalEncrypted::class,
    ];

    public static $satisfactory_options = [
        1 => 'Great',
        2 => 'Okay',
        3 => 'Not Good',
    ];

    public static $response_times = [
        15 * \Util::SECONDS_IN_A_MINUTE => '< 15 min',
        1 * \Util::SECONDS_IN_A_HOUR => '15-60 min',
        2 * \Util::SECONDS_IN_A_HOUR => '1-2 hours',
        3 * \Util::SECONDS_IN_A_HOUR => '2-3 hours',
        6 * \Util::SECONDS_IN_A_HOUR => '3-6 hours',
        12 * \Util::SECONDS_IN_A_HOUR => '6-12 hours',
        1 * \Util::SECONDS_IN_A_DAY => '12-24 hours',
        2 * \Util::SECONDS_IN_A_DAY => '1-2 days',
        100 * \Util::SECONDS_IN_A_YEAR => '2+ days',
    ];

    public function getHumandateAttribute() {
        return $this->humandate;
    }
    /**
     * Thread relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     *
     * @codeCoverageIgnore
     */
    public function thread()
    {
        return $this->belongsTo(Thread::class, 'thread_id', 'id');
    }

    /**
     * User relationship.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     *
     * @codeCoverageIgnore
     */
    public function user()
    {
        return $this->belongsTo(Member::class, 'member_id');
    }

    public function admin_user()
    {
        return $this->belongsTo(User::class, 'member_id');
    }

    public function member(){
        return $this->user();
    }

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

    /**
     * Recipients of this message.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function recipients()
    {
        return $this->participants()->where('member_id', '!=', $this->member_id);
    }

    public function messagesUnread()
    {
        return $this->hasMany(MessagesRead::class, 'message_id')->where('member_id', Auth::getLoggedInMember()->id);
    }

    public function reports()
    {
        return $this->morphMany(Reports::class, 'reportable');
    }

    public function parsedText()
    {
        return preg_replace('!(((f|ht)tp(s)?://)[-a-zA-Zа-яА-Я()0-9@:%_+.~#?&;//=]+)!i', '<a target="_blank" href="$1">$1</a>', $this->text);
    }


    public static function getUnread($admin_id, $include_admin_messages = false)
    {
        $threads = Thread::getAllAssignedToUser();
        $threadIds = $threads->pluck('id');

        // Get unread counts from customers per thread in one query
        $unreadCounts = Message::query()
            ->whereIn('thread_id', $threadIds)
            ->whereNull('read_at')
            ->where(function ($query) {
                $query->where('admin', 0)->orWhere('private', 1);
            })
            ->selectRaw('thread_id, COUNT(*) as unread_count')
            ->groupBy('thread_id')
            ->pluck('unread_count');

        return $unreadCounts->sum();
    }

    /**
     * Get author of message
     *
     * @return string
     */
    public function authorName(): string
    {
        if ($this->admin) {
            return $this->admin_user->name;
        }
        return $this->member->addressBilling->firstname . ' ' . $this->member->addressBilling->lastname;
    }
}
