<?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\Support\Str;

/**
 * Model: RHealthStory (Health Success/Impact Story)
 * 
 * Represents impact and success stories submitted by users or guests.
 * Supports public submission with moderation workflow.
 * 
 * @property int $id
 * @property int|null $campaign_id
 * @property int|null $user_id
 * @property string|null $author_name
 * @property string|null $author_email
 * @property string|null $author_phone
 * @property string $title
 * @property string $slug
 * @property string|null $excerpt
 * @property string $content
 * @property string|null $location
 * @property string|null $featured_image
 * @property array|null $gallery
 * @property string|null $video_url
 * @property string $status
 * @property bool $is_featured
 * @property string|null $rejection_reason
 * @property int|null $moderated_by
 * @property \Carbon\Carbon|null $moderated_at
 * @property \Carbon\Carbon|null $published_at
 * @property int $views_count
 * @property int $shares_count
 */
class RHealthStory extends Model
{
    use HasFactory, SoftDeletes;

    protected $table = 'r_health_stories';

    protected $fillable = [
        'campaign_id',
        'user_id',
        'author_name',
        'author_email',
        'author_phone',
        'title',
        'slug',
        'excerpt',
        'content',
        'location',
        'featured_image',
        'gallery',
        'video_url',
        'status',
        'is_featured',
        'rejection_reason',
        'moderated_by',
        'moderated_at',
        'published_at',
        'meta_title',
        'meta_description',
        'views_count',
        'shares_count',
    ];

    protected $casts = [
        'is_featured' => 'boolean',
        'gallery' => 'array',
        'moderated_at' => 'datetime',
        'published_at' => 'datetime',
        'views_count' => 'integer',
        'shares_count' => 'integer',
    ];

    /**
     * Status constants.
     */
    const STATUS_DRAFT = 'draft';
    const STATUS_PENDING_REVIEW = 'pending_review';
    const STATUS_APPROVED = 'approved';
    const STATUS_REJECTED = 'rejected';
    const STATUS_PUBLISHED = 'published';

    /**
     * Get the associated campaign.
     */
    public function campaign(): BelongsTo
    {
        return $this->belongsTo(RCampaign::class, 'campaign_id');
    }

    /**
     * Get the registered user author (if any).
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    /**
     * Get the moderator.
     */
    public function moderator(): BelongsTo
    {
        return $this->belongsTo(User::class, 'moderated_by');
    }

    /**
     * Scope: Published stories.
     */
    public function scopePublished($query)
    {
        return $query->where('status', self::STATUS_PUBLISHED)
                     ->whereNotNull('published_at')
                     ->where('published_at', '<=', now());
    }

    /**
     * Scope: Pending review.
     */
    public function scopePendingReview($query)
    {
        return $query->where('status', self::STATUS_PENDING_REVIEW);
    }

    /**
     * Scope: Approved stories.
     */
    public function scopeApproved($query)
    {
        return $query->whereIn('status', [self::STATUS_APPROVED, self::STATUS_PUBLISHED]);
    }

    /**
     * Scope: Featured stories.
     */
    public function scopeFeatured($query)
    {
        return $query->where('is_featured', true);
    }

    /**
     * Scope: By guest author.
     */
    public function scopeGuestSubmitted($query)
    {
        return $query->whereNull('user_id');
    }

    /**
     * Check if story is from a guest.
     */
    public function isGuestSubmission(): bool
    {
        return $this->user_id === null;
    }

    /**
     * Get the author name (user or guest).
     */
    public function getAuthorNameAttribute(): string
    {
        if ($this->user) {
            return $this->user->name;
        }
        
        return $this->attributes['author_name'] ?? 'Anonymous';
    }

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

    /**
     * Check if story can be edited.
     */
    public function isEditable(): bool
    {
        return in_array($this->status, [self::STATUS_DRAFT, self::STATUS_REJECTED]);
    }

    /**
     * Approve the story.
     */
    public function approve(int $moderatorId): void
    {
        $this->update([
            'status' => self::STATUS_APPROVED,
            'moderated_by' => $moderatorId,
            'moderated_at' => now(),
            'rejection_reason' => null,
        ]);
    }

    /**
     * Publish the story.
     */
    public function publish(): void
    {
        $this->update([
            'status' => self::STATUS_PUBLISHED,
            'published_at' => now(),
        ]);
    }

    /**
     * Reject the story.
     */
    public function reject(int $moderatorId, string $reason): void
    {
        $this->update([
            'status' => self::STATUS_REJECTED,
            'moderated_by' => $moderatorId,
            'moderated_at' => now(),
            'rejection_reason' => $reason,
        ]);
    }

    /**
     * Get status color for UI.
     */
    public function getStatusColorAttribute(): string
    {
        return match($this->status) {
            self::STATUS_DRAFT => 'gray',
            self::STATUS_PENDING_REVIEW => 'blue',
            self::STATUS_APPROVED => 'green',
            self::STATUS_REJECTED => 'red',
            self::STATUS_PUBLISHED => 'purple',
            default => 'gray',
        };
    }

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

    /**
     * Increment share count.
     */
    public function incrementShares(): void
    {
        $this->increment('shares_count');
    }

    /**
     * Generate slug from title.
     */
    public static function generateSlug(string $title): string
    {
        $slug = Str::slug($title);
        $count = static::where('slug', 'LIKE', "{$slug}%")->count();
        
        return $count > 0 ? "{$slug}-{$count}" : $slug;
    }
}
