<?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;

/**
 * KnowledgeBaseAnswer Model
 * 
 * Represents an answer to a knowledge base question.
 * Supports accepted answers and helpful voting.
 * 
 * @property int $id
 * @property string $content
 * @property int $question_id
 * @property int $user_id
 * @property bool $is_published
 * @property bool $is_accepted
 * @property \Carbon\Carbon|null $accepted_at
 * @property int|null $accepted_by
 * @property int $helpful_count
 * @property int $not_helpful_count
 * @property int $view_count
 * @property int $sort_order
 * @property \Carbon\Carbon|null $created_at
 * @property \Carbon\Carbon|null $updated_at
 * @property \Carbon\Carbon|null $deleted_at
 */
class KnowledgeBaseAnswer extends Model
{
    use HasFactory, SoftDeletes;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'content',
        'question_id',
        'user_id',
        'is_published',
        'is_accepted',
        'accepted_at',
        'accepted_by',
        'helpful_count',
        'not_helpful_count',
        'view_count',
        'sort_order',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'is_published' => 'boolean',
        'is_accepted' => 'boolean',
        'accepted_at' => 'datetime',
        'helpful_count' => 'integer',
        'not_helpful_count' => 'integer',
        'view_count' => 'integer',
        'sort_order' => 'integer',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
        'deleted_at' => 'datetime',
    ];

    /**
     * The attributes that should be appended.
     *
     * @var array<int, string>
     */
    protected $appends = [
        'content_preview',
        'time_ago',
        'helpful_percentage',
    ];

    /**
     * The "booted" method of the model.
     */
    protected static function booted(): void
    {
        static::created(function (self $answer) {
            $answer->question->updateAnswerCount();
        });

        static::updated(function (self $answer) {
            if ($answer->isDirty('is_published')) {
                $answer->question->updateAnswerCount();
            }
        });

        static::deleted(function (self $answer) {
            $answer->question->updateAnswerCount();
        });
    }

    /**
     * Get the question this answer belongs to.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function question(): BelongsTo
    {
        return $this->belongsTo(KnowledgeBaseQuestion::class, 'question_id');
    }

    /**
     * Get the user who created this answer.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /**
     * Get the user who accepted this answer.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function acceptedBy(): BelongsTo
    {
        return $this->belongsTo(User::class, 'accepted_by');
    }

    /**
     * Scope a query to only include published answers.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopePublished($query)
    {
        return $query->where('is_published', true);
    }

    /**
     * Scope a query to only include accepted answers.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeAccepted($query)
    {
        return $query->where('is_accepted', true);
    }

    /**
     * Scope a query to order by sort order.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeOrdered($query)
    {
        return $query->orderBy('sort_order')->orderBy('created_at');
    }

    /**
     * Scope a query to order by most helpful.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeMostHelpful($query)
    {
        return $query->orderByDesc('helpful_count');
    }

    /**
     * Mark this answer as accepted.
     *
     * @param \App\Models\User $user
     * @return void
     */
    public function accept(User $user): void
    {
        // Remove accepted status from other answers
        static::where('question_id', $this->question_id)
            ->where('is_accepted', true)
            ->update([
                'is_accepted' => false,
                'accepted_at' => null,
                'accepted_by' => null,
            ]);

        // Mark this answer as accepted
        $this->update([
            'is_accepted' => true,
            'accepted_at' => now(),
            'accepted_by' => $user->id,
        ]);
    }

    /**
     * Unmark this answer as accepted.
     *
     * @return void
     */
    public function unaccept(): void
    {
        $this->update([
            'is_accepted' => false,
            'accepted_at' => null,
            'accepted_by' => null,
        ]);
    }

    /**
     * Check if answer belongs to user.
     *
     * @param \App\Models\User $user
     * @return bool
     */
    public function isOwnedBy(User $user): bool
    {
        return $this->user_id === $user->id;
    }

    /**
     * Increment the helpful count.
     *
     * @return void
     */
    public function incrementHelpful(): void
    {
        $this->increment('helpful_count');
    }

    /**
     * Increment the not helpful count.
     *
     * @return void
     */
    public function incrementNotHelpful(): void
    {
        $this->increment('not_helpful_count');
    }

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

    /**
     * Get content preview for display.
     *
     * @return string
     */
    public function getContentPreviewAttribute(): string
    {
        return \Illuminate\Support\Str::limit(strip_tags($this->content), 200);
    }

    /**
     * Get time ago string.
     *
     * @return string
     */
    public function getTimeAgoAttribute(): string
    {
        return $this->created_at->diffForHumans();
    }

    /**
     * Get helpful percentage.
     *
     * @return int
     */
    public function getHelpfulPercentageAttribute(): int
    {
        $total = $this->helpful_count + $this->not_helpful_count;
        
        if ($total === 0) {
            return 0;
        }

        return (int) round(($this->helpful_count / $total) * 100);
    }

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