<?php

namespace App\Services\Posts;

use App\Models\Achievement;
use App\Models\Post;
use App\Models\PostTarget;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * Creates achievement posts for significant milestones.
 *
 * Achievement types stored in post.meta.achievement_type:
 *   - follower_100 / follower_500 / follower_1000 / follower_5000 / follower_10000
 *   - artwork_100_views / artwork_1000_views / artwork_1000_favs
 *   - award_received
 */
class PostAchievementService
{
    private const FOLLOWER_MILESTONES = [100, 500, 1_000, 5_000, 10_000, 50_000];
    private const VIEW_MILESTONES     = [100, 1_000, 10_000, 100_000];
    private const FAV_MILESTONES      = [10, 100, 500, 1_000];

    /**
     * Check if a follower count crosses a milestone and create an achievement post.
     */
    public function maybeFollowerMilestone(User $user, int $newFollowerCount): void
    {
        foreach (self::FOLLOWER_MILESTONES as $milestone) {
            if ($newFollowerCount === $milestone) {
                $this->createAchievementPost($user, "follower_{$milestone}", [
                    'milestone' => $milestone,
                    'message'   => "🎉 Just reached {$milestone} followers! Thank you all!",
                ]);
                break;
            }
        }
    }

    /**
     * Check if an artwork's view count crosses a milestone.
     */
    public function maybeArtworkViewMilestone(User $user, int $artworkId, int $newViewCount): void
    {
        foreach (self::VIEW_MILESTONES as $milestone) {
            if ($newViewCount === $milestone) {
                $this->createAchievementPost($user, "artwork_{$milestone}_views", [
                    'artwork_id' => $artworkId,
                    'milestone'  => $milestone,
                    'message'    => "🎨 One of my artworks just hit {$milestone} views!",
                ], $artworkId);
                break;
            }
        }
    }

    /**
     * Create an achievement post for receiving an award.
     */
    public function awardReceived(User $user, string $awardName, ?int $artworkId = null): void
    {
        $this->createAchievementPost($user, 'award_received', [
            'award_name' => $awardName,
            'artwork_id' => $artworkId,
            'message'    => "🏆 Just received the \"{$awardName}\" award!",
        ], $artworkId);
    }

    public function achievementUnlocked(User $user, Achievement $achievement): void
    {
        $this->createAchievementPost($user, 'unlock_' . $achievement->slug, [
            'achievement_id' => $achievement->id,
            'achievement_name' => $achievement->name,
            'message' => '🎉 Unlocked achievement: ' . $achievement->name,
            'xp_reward' => (int) $achievement->xp_reward,
        ]);
    }

    // ─────────────────────────────────────────────────────────────────────────

    private function createAchievementPost(
        User $user,
        string $achievementType,
        array $meta,
        ?int $artworkId = null,
    ): void {
        // Deduplicate: don't create the same achievement post twice
        $exists = Post::where('user_id', $user->id)
            ->where('type', Post::TYPE_ACHIEVEMENT)
            ->whereJsonContains('meta->achievement_type', $achievementType)
            ->exists();

        if ($exists) {
            return;
        }

        DB::transaction(function () use ($user, $achievementType, $meta, $artworkId) {
            $post = Post::create([
                'user_id'    => $user->id,
                'type'       => Post::TYPE_ACHIEVEMENT,
                'visibility' => Post::VISIBILITY_PUBLIC,
                'body'       => $meta['message'] ?? null,
                'status'     => Post::STATUS_PUBLISHED,
                'meta'       => array_merge($meta, ['achievement_type' => $achievementType]),
            ]);

            if ($artworkId) {
                PostTarget::create([
                    'post_id'     => $post->id,
                    'target_type' => 'artwork',
                    'target_id'   => $artworkId,
                ]);
            }
        });

        Log::info("PostAchievementService: created '{$achievementType}' post for user #{$user->id}");
    }
}
