<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class CompetitorPost extends Model
{
    use HasFactory;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'competitor_brand_id',
        'platform',
        'platform_post_id',
        'post_type',
        'caption',
        'content',
        'media',
        'permalink',
        'published_at',
        'metrics',
        'engagement_rate',
        'hashtags',
        'mentions',
        'sentiment',
        'topics',
        'raw_data',
        'last_checked_at',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'media' => 'array',
        'metrics' => 'array',
        'hashtags' => 'array',
        'mentions' => 'array',
        'topics' => 'array',
        'raw_data' => 'array',
        'published_at' => 'datetime',
        'last_checked_at' => 'datetime',
        'engagement_rate' => 'decimal:2',
    ];

    /**
     * Get the competitor brand that owns the post.
     */
    public function competitorBrand()
    {
        return $this->belongsTo(CompetitorBrand::class);
    }

    /**
     * Get the alerts related to this post.
     */
    public function alerts()
    {
        return $this->hasMany(CompetitorAlert::class);
    }

    /**
     * Get a specific metric value.
     *
     * @param string $metric
     * @return int|float|null
     */
    public function getMetric(string $metric)
    {
        return $this->metrics[$metric] ?? null;
    }

    /**
     * Get likes count from metrics.
     *
     * @return int
     */
    public function getLikesCount()
    {
        return $this->getMetric('likes') ?? 0;
    }

    /**
     * Get comments count from metrics.
     *
     * @return int
     */
    public function getCommentsCount()
    {
        return $this->getMetric('comments') ?? 0;
    }

    /**
     * Get shares count from metrics.
     *
     * @return int
     */
    public function getSharesCount()
    {
        return $this->getMetric('shares') ?? 0;
    }

    /**
     * Get views count from metrics.
     *
     * @return int
     */
    public function getViewsCount()
    {
        return $this->getMetric('views') ?? 0;
    }

    /**
     * Get saves count from metrics.
     *
     * @return int
     */
    public function getSavesCount()
    {
        return $this->getMetric('saves') ?? 0;
    }

    /**
     * Calculate total engagement.
     *
     * @return int
     */
    public function getTotalEngagement()
    {
        return $this->getLikesCount() + 
               $this->getCommentsCount() + 
               $this->getSharesCount() + 
               $this->getSavesCount();
    }

    /**
     * Calculate engagement rate if not already set.
     *
     * @return float
     */
    public function calculateEngagementRate()
    {
        $views = $this->getViewsCount();
        if ($views <= 0) {
            return 0;
        }

        $engagement = $this->getTotalEngagement();
        return round(($engagement / $views) * 100, 2);
    }

    /**
     * Scope a query to only include posts from a specific platform.
     */
    public function scopePlatform($query, string $platform)
    {
        return $query->where('platform', $platform);
    }

    /**
     * Scope a query to only include posts within a date range.
     */
    public function scopeDateRange($query, $startDate, $endDate)
    {
        return $query->whereBetween('published_at', [$startDate, $endDate]);
    }

    /**
     * Scope a query to order by engagement rate.
     */
    public function scopeTopPerforming($query, $limit = 10)
    {
        return $query->orderBy('engagement_rate', 'desc')->limit($limit);
    }

    /**
     * Scope a query to filter by sentiment.
     */
    public function scopeSentiment($query, string $sentiment)
    {
        return $query->where('sentiment', $sentiment);
    }
}