<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Str;
use Laravel\Scout\Searchable;

use App\Models\MessageRead;

/**
 * @property int         $id
 * @property int         $conversation_id
 * @property int         $sender_id
 * @property string      $body
 * @property \Carbon\Carbon|null $edited_at
 * @property \Carbon\Carbon|null $deleted_at
 * @property \Carbon\Carbon $created_at
 * @property \Carbon\Carbon $updated_at
 */
class Message extends Model
{
    use HasFactory, SoftDeletes, Searchable;

    protected $fillable = [
        'uuid',
        'client_temp_id',
        'conversation_id',
        'sender_id',
        'message_type',
        'body',
        'meta_json',
        'reply_to_message_id',
        'edited_at',
    ];

    protected $casts = [
        'meta_json' => 'array',
        'edited_at' => 'datetime',
    ];

    protected static function booted(): void
    {
        static::creating(function (self $message): void {
            if (! $message->uuid) {
                $message->uuid = (string) Str::uuid();
            }
        });
    }

    // ── Relationships ────────────────────────────────────────────────────────

    public function conversation(): BelongsTo
    {
        return $this->belongsTo(Conversation::class);
    }

    public function sender(): BelongsTo
    {
        return $this->belongsTo(User::class, 'sender_id');
    }

    public function reactions(): HasMany
    {
        return $this->hasMany(MessageReaction::class);
    }

    public function attachments(): HasMany
    {
        return $this->hasMany(MessageAttachment::class);
    }

    public function reads(): HasMany
    {
        return $this->hasMany(MessageRead::class);
    }

    public function setBodyAttribute(?string $value): void
    {
        $sanitized = trim(strip_tags((string) $value));
        $this->attributes['body'] = $sanitized;
    }

    public function searchableAs(): string
    {
        return config('messaging.search.index', 'messages');
    }

    public function shouldBeSearchable(): bool
    {
        return $this->deleted_at === null;
    }

    public function toSearchableArray(): array
    {
        return [
            'id' => (int) $this->id,
            'conversation_id' => (int) $this->conversation_id,
            'sender_id' => (int) $this->sender_id,
            'sender_username' => (string) ($this->sender?->username ?? ''),
            'body_text' => trim(strip_tags((string) $this->body)),
            'created_at' => optional($this->created_at)->timestamp ?? now()->timestamp,
            'has_attachments' => $this->relationLoaded('attachments')
                ? $this->attachments->isNotEmpty()
                : $this->attachments()->exists(),
        ];
    }
}
