<?php

namespace App\Models;

use App\Enums\ContactBudget;
use App\Enums\ContactService;
use App\Enums\ContactStatus;
use Database\Factories\ContactSubmissionFactory;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;

/**
 * @property int $id
 * @property string $name
 * @property string $phone
 * @property string $email
 * @property ContactService $service
 * @property Carbon|null $event_date
 * @property ContactBudget|null $budget
 * @property string $message
 * @property string|null $ip_address
 * @property string|null $user_agent
 * @property ContactStatus|null $status
 * @property Carbon|null $created_at
 * @property Carbon|null $updated_at
 * @property-read string $message_preview
 * @property-read int $days_old
 */
#[Fillable(['name', 'phone', 'email', 'service', 'event_date', 'budget', 'message', 'ip_address', 'user_agent', 'status'])]
class ContactSubmission extends Model
{
    /** @use HasFactory<ContactSubmissionFactory> */
    use HasFactory;

    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'contact_submissions';

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'event_date' => 'date',
            'status' => ContactStatus::class,
            'service' => ContactService::class,
            'budget' => ContactBudget::class,
        ];
    }

    /**
     * Scope a query to only include submissions with the given status.
     *
     * Passing `null` or `'all'` leaves the query unfiltered, matching the
     * legacy admin panel's status filter behaviour.
     *
     * @param  Builder<ContactSubmission>  $query
     * @return Builder<ContactSubmission>
     */
    public function scopeStatus(Builder $query, ?string $status): Builder
    {
        if ($status === null || $status === 'all') {
            return $query;
        }

        return $query->where('status', $status);
    }

    /**
     * Scope a query to order submissions newest first, matching the legacy
     * admin panel's default listing order.
     *
     * @param  Builder<ContactSubmission>  $query
     * @return Builder<ContactSubmission>
     */
    public function scopeLatestFirst(Builder $query): Builder
    {
        return $query->orderByDesc('created_at');
    }

    /**
     * Get a truncated preview of the message, mirroring the legacy
     * `contact_submissions_view` preview column.
     *
     * @return Attribute<string, never>
     */
    protected function messagePreview(): Attribute
    {
        return Attribute::make(
            get: fn (): string => Str::limit($this->message, 100, '...'),
        );
    }

    /**
     * Get the number of whole days since the submission was created.
     *
     * @return Attribute<int, never>
     */
    protected function daysOld(): Attribute
    {
        return Attribute::make(
            get: fn (): int => (int) ($this->created_at?->diffInDays(now()) ?? 0),
        );
    }
}
