<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;

class ContentPage extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'title',
        'slug',
        'content',
        'excerpt',
        'language',
        'status',
        'template',
        'seo_title',
        'seo_description',
        'seo_keywords',
        'featured_image',
        'author_id',
        'published_at',
        'related_pages',
        'tags',
        'metadata',
        'view_count',
    ];

    protected $casts = [
        'published_at' => 'datetime',
        'related_pages' => 'array',
        'tags' => 'array',
        'metadata' => 'array',
        'view_count' => 'integer',
    ];

    /**
     * Content status constants
     */
    public const STATUS_DRAFT = 'draft';
    public const STATUS_PUBLISHED = 'published';
    public const STATUS_ARCHIVED = 'archived';

    /**
     * Template constants
     */
    public const TEMPLATE_DEFAULT = 'default';
    public const TEMPLATE_FAQ = 'faq';
    public const TEMPLATE_CONTACT = 'contact';
    public const TEMPLATE_ABOUT = 'about';

    /**
     * Get the author of the content page
     */
    public function author()
    {
        return $this->belongsTo(User::class, 'author_id');
    }

    /**
     * Get menu items that link to this page
     */
    public function menuItems(): HasMany
    {
        return $this->hasMany(MenuItem::class, 'content_page_id');
    }

    /**
     * Scope for published pages
     */
    public function scopePublished($query)
    {
        return $query->where('status', self::STATUS_PUBLISHED)
                     ->where('published_at', '<=', now());
    }

    /**
     * Scope for active/visible pages
     */
    public function scopeActive($query)
    {
        return $query->published();
    }

    /**
     * Scope for pages by language
     */
    public function scopeByLanguage($query, string $language)
    {
        return $query->where('language', $language);
    }

    /**
     * Scope for pages by template
     */
    public function scopeByTemplate($query, string $template)
    {
        return $query->where('template', $template);
    }

    /**
     * Check if page is published
     */
    public function isPublished(): bool
    {
        return $this->status === self::STATUS_PUBLISHED && 
               $this->published_at <= now();
    }

    /**
     * Check if page is draft
     */
    public function isDraft(): bool
    {
        return $this->status === self::STATUS_DRAFT;
    }

    /**
     * Get formatted content for Telegram
     */
    public function getFormattedContentAttribute(): string
    {
        $content = $this->content;
        
        // Replace some common markdown-like formatting for Telegram
        $content = str_replace(['**', '__'], '*', $content); // Bold
        $content = str_replace(['_', '`'], '_', $content); // Italic/code
        
        // Remove HTML tags if any
        $content = strip_tags($content);
        
        // Limit content length for Telegram (max 4096 characters)
        if (strlen($content) > 4000) {
            $content = substr($content, 0, 3997) . '...';
        }
        
        return $content;
    }

    /**
     * Get related pages
     */
    public function getRelatedPages()
    {
        if (empty($this->related_pages)) {
            return collect();
        }

        return self::published()
            ->whereIn('id', $this->related_pages)
            ->get();
    }

    /**
     * Increment view count
     */
    public function incrementViewCount(): void
    {
        $this->increment('view_count');
    }

    /**
     * Get content pages by tags
     */
    public static function getByTags(array $tags)
    {
        return self::published()
            ->where(function ($query) use ($tags) {
                foreach ($tags as $tag) {
                    $query->orWhereJsonContains('tags', $tag);
                }
            })
            ->get();
    }

    /**
     * Search content pages
     */
    public static function search(string $query)
    {
        return self::published()
            ->where(function ($q) use ($query) {
                $q->where('title', 'LIKE', "%{$query}%")
                  ->orWhere('content', 'LIKE', "%{$query}%")
                  ->orWhere('excerpt', 'LIKE', "%{$query}%")
                  ->orWhereJsonContains('tags', $query);
            })
            ->orderBy('view_count', 'desc')
            ->get();
    }

    /**
     * Get popular pages
     */
    public static function getPopular(int $limit = 5)
    {
        return self::published()
            ->orderBy('view_count', 'desc')
            ->limit($limit)
            ->get();
    }

    /**
     * Get recent pages
     */
    public static function getRecent(int $limit = 5)
    {
        return self::published()
            ->orderBy('published_at', 'desc')
            ->limit($limit)
            ->get();
    }

    /**
     * Boot model events
     */
    protected static function boot()
    {
        parent::boot();

        // Automatically generate slug from title if not provided
        static::creating(function ($page) {
            if (empty($page->slug)) {
                $page->slug = Str::slug($page->title);
            }
            
            if (empty($page->language)) {
                $page->language = config('app.locale', 'fa');
            }

            if (empty($page->template)) {
                $page->template = self::TEMPLATE_DEFAULT;
            }

            if (empty($page->status)) {
                $page->status = self::STATUS_DRAFT;
            }
        });

        // Ensure unique slug
        static::saving(function ($page) {
            $count = self::where('slug', $page->slug)
                ->where('id', '!=', $page->id)
                ->count();

            if ($count > 0) {
                $page->slug = $page->slug . '-' . time();
            }
            
            // Auto-generate excerpt if not provided
            if (empty($page->excerpt) && $page->content) {
                $page->excerpt = Str::limit(strip_tags($page->content), 150);
            }
        });
    }
}