<?php

declare(strict_types=1);

namespace App\Observers;

use App\Models\ArtworkComment;
use App\Services\ArtworkStatsService;
use App\Services\Profile\CreatorJourneyService;
use App\Services\UserStatsService;
use App\Services\UserMentionSyncService;
use App\Services\XPService;
use Illuminate\Support\Facades\DB;

/**
 * Updates the artwork creator's comments_received_count and last_active_at
 * when a comment is created or (soft-)deleted.
 */
class ArtworkCommentObserver
{
    public function __construct(
        private readonly ArtworkStatsService $artworkStats,
        private readonly UserStatsService $userStats,
        private readonly CreatorJourneyService $journeys,
        private readonly UserMentionSyncService $mentionSync,
        private readonly XPService $xp,
    ) {}

    public function created(ArtworkComment $comment): void
    {
        $creatorId = $this->creatorId($comment->artwork_id);
        if ($creatorId) {
            $this->userStats->incrementCommentsReceived($creatorId);
            $this->journeys->requestRebuild($creatorId);
        }

        // The commenter is "active"
        $this->userStats->ensureRow($comment->user_id);
        $this->userStats->setLastActiveAt($comment->user_id);
        $this->xp->awardCommentCreated((int) $comment->user_id, (int) $comment->id, 'artwork');
        $this->mentionSync->syncForComment($comment);
        $this->artworkStats->syncEngagementCounts((int) $comment->artwork_id);
    }

    public function updated(ArtworkComment $comment): void
    {
        if ($comment->wasChanged(['content', 'raw_content', 'rendered_content', 'parent_id'])) {
            $this->mentionSync->syncForComment($comment);
        }
    }

    /** Soft delete. */
    public function deleted(ArtworkComment $comment): void
    {
        $creatorId = $this->creatorId($comment->artwork_id);
        if ($creatorId) {
            $this->userStats->decrementCommentsReceived($creatorId);
            $this->journeys->requestRebuild($creatorId);
        }

        $this->mentionSync->deleteForComment((int) $comment->id);
        $this->artworkStats->syncEngagementCounts((int) $comment->artwork_id);
    }

    /** Hard delete after soft delete — already decremented; nothing to do. */
    public function forceDeleted(ArtworkComment $comment): void
    {
        // Only decrement if the comment was NOT already soft-deleted
        // (to avoid double-decrement).
        if ($comment->deleted_at === null) {
            $creatorId = $this->creatorId($comment->artwork_id);
            if ($creatorId) {
                $this->userStats->decrementCommentsReceived($creatorId);
                $this->journeys->requestRebuild($creatorId);
            }
        }

        $this->mentionSync->deleteForComment((int) $comment->id);
        $this->artworkStats->syncEngagementCounts((int) $comment->artwork_id);
    }

    public function restored(ArtworkComment $comment): void
    {
        $this->mentionSync->syncForComment($comment);
        $this->artworkStats->syncEngagementCounts((int) $comment->artwork_id);

        $creatorId = $this->creatorId($comment->artwork_id);
        if ($creatorId) {
            $this->journeys->requestRebuild($creatorId);
        }
    }

    private function creatorId(int $artworkId): ?int
    {
        $id = DB::table('artworks')
            ->where('id', $artworkId)
            ->value('user_id');

        return $id !== null ? (int) $id : null;
    }
}
