<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Str;

class BlogPost extends Model
{
    use SoftDeletes;

    protected $fillable = [
        'title', 'slug', 'excerpt', 'content', 'cover_image',
        'status', 'category', 'tags', 'author_id', 'published_at',
        'meta_title', 'meta_description',
    ];

    /**
     * Always include the normalised cover image URL in API responses.
     * This lets the Vue admin panel use cover_image_url directly instead
     * of trying to build a URL from the raw storage path.
     */
    protected $appends = ['cover_image_url'];

    protected function casts(): array
    {
        return [
            'tags'         => 'array',
            'published_at' => 'datetime',
        ];
    }

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

    public function scopePublished($query)
    {
        return $query->where('status', 'published')
            ->whereNotNull('published_at');
    }

    /** Estimated reading time in minutes (≈200 words/min). */
    public function getReadingTimeAttribute(): int
    {
        $wordCount = str_word_count(strip_tags($this->content ?? ''));
        return max(1, (int) ceil($wordCount / 200));
    }

    /** SEO title: uses meta_title if set, falls back to title. */
    public function getSeoTitleAttribute(): string
    {
        return $this->meta_title ?: $this->title;
    }

    /** SEO description: uses meta_description if set, falls back to excerpt. */
    public function getSeoDescriptionAttribute(): string
    {
        return $this->meta_description ?: ($this->excerpt ?? Str::limit(strip_tags($this->content ?? ''), 155));
    }

    /**
     * Normalised cover image URL usable in any context.
     * Always returns a root-relative path (/storage/...) so it works on any
     * host or port (XAMPP, artisan serve, production) without APP_URL issues.
     *
     * Legacy absolute URLs (http://host/storage/...) are also normalised
     * to their path component so existing posts keep rendering correctly.
     */
    public function getCoverImageUrlAttribute(): ?string
    {
        if (!$this->cover_image) {
            return null;
        }
        // Already root-relative (e.g. "/storage/blog/image.png") — return as-is
        if (str_starts_with($this->cover_image, '/storage/')) {
            return $this->cover_image;
        }
        // Legacy absolute URL (http://... or https://...) — strip the host,
        // keep only the path so it works on any port or subdomain
        if (str_starts_with($this->cover_image, 'http://') || str_starts_with($this->cover_image, 'https://')) {
            $path = parse_url($this->cover_image, PHP_URL_PATH);
            return $path ?: $this->cover_image;
        }
        // Raw storage path (e.g. "blog/image.png") — prepend /storage/
        return '/storage/' . ltrim($this->cover_image, '/');
    }

    protected static function booted(): void
    {
        static::creating(function (BlogPost $post) {
            if (empty($post->slug)) {
                $post->slug = Str::slug($post->title) . '-' . Str::lower(Str::random(5));
            }
        });
    }
}
