<?php

namespace App\Http\Controllers\Api\Posts;

use App\Events\Posts\PostCommented;
use App\Http\Controllers\Controller;
use App\Http\Requests\Posts\CreateCommentRequest;
use App\Models\Post;
use App\Models\PostComment;
use App\Services\ContentSanitizer;
use App\Services\Posts\PostCountersService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\RateLimiter;

class PostCommentController extends Controller
{
    public function __construct(private PostCountersService $counters) {}

    // ─────────────────────────────────────────────────────────────────────────
    // List
    // ─────────────────────────────────────────────────────────────────────────

    public function index(Request $request, int $postId): JsonResponse
    {
        $post     = Post::findOrFail($postId);
        $page     = max(1, (int) $request->query('page', 1));

        $comments = PostComment::with(['user', 'user.profile'])
            ->where('post_id', $post->id)
            ->orderByDesc('is_highlighted') // highlighted first
            ->orderBy('created_at')
            ->paginate(20, ['*'], 'page', $page);

        $formatted = $comments->getCollection()->map(fn ($c) => $this->formatComment($c));

        return response()->json([
            'data' => $formatted,
            'meta' => [
                'total'        => $comments->total(),
                'current_page' => $comments->currentPage(),
                'last_page'    => $comments->lastPage(),
                'per_page'     => $comments->perPage(),
            ],
        ]);
    }

    // ─────────────────────────────────────────────────────────────────────────
    // Store
    // ─────────────────────────────────────────────────────────────────────────

    public function store(CreateCommentRequest $request, int $postId): JsonResponse
    {
        $user = $request->user();

        // Rate limit: 30 comments per hour
        $key = 'comment_post:' . $user->id;
        if (RateLimiter::tooManyAttempts($key, 30)) {
            $seconds = RateLimiter::availableIn($key);
            return response()->json([
                'message' => "You're commenting too quickly. Please wait {$seconds} seconds.",
            ], 429);
        }
        RateLimiter::hit($key, 3600);

        $post   = Post::findOrFail($postId);
        $body   = ContentSanitizer::render($request->input('body'));

        $comment = PostComment::create([
            'post_id' => $post->id,
            'user_id' => $user->id,
            'body'    => $body,
        ]);

        $this->counters->incrementComments($post);

        // Fire event for notification
        if ($post->user_id !== $user->id) {
            event(new PostCommented($post, $comment, $user));
        }

        $comment->load(['user', 'user.profile']);

        return response()->json(['comment' => $this->formatComment($comment)], 201);
    }

    // ─────────────────────────────────────────────────────────────────────────
    // Destroy
    // ─────────────────────────────────────────────────────────────────────────

    public function destroy(Request $request, int $postId, int $commentId): JsonResponse
    {
        $comment = PostComment::where('post_id', $postId)->findOrFail($commentId);
        Gate::authorize('delete', $comment);

        $comment->delete();
        $this->counters->decrementComments(Post::findOrFail($postId));

        return response()->json(['message' => 'Comment deleted.']);
    }

    // ─────────────────────────────────────────────────────────────────────────
    // Format
    // ─────────────────────────────────────────────────────────────────────────

    private function formatComment(PostComment $comment): array
    {
        return [
            'id'             => $comment->id,
            'body'           => $comment->body,
            'is_highlighted' => (bool) $comment->is_highlighted,
            'created_at'     => $comment->created_at->toISOString(),
            'author'         => [
                'id'       => $comment->user->id,
                'username' => $comment->user->username,
                'name'     => $comment->user->name,
                'avatar'   => $comment->user->profile?->avatar_url ?? null,
                'level'    => (int) ($comment->user->level ?? 1),
                'rank'     => (string) ($comment->user->rank ?? 'Newbie'),
            ],
        ];
    }
}
