<?php

namespace App\Http\Controllers\Api\V1;

use App\Actions\Comment\CreateCommentAction;
use App\DTOs\CommentData;
use App\Http\Controllers\Controller;
use App\Http\Requests\Comment\StoreCommentRequest;
use App\Http\Resources\CommentResource;
use App\Models\Announcement;
use App\Models\Category;
use App\Models\Course;
use App\Repositories\Contracts\CommentRepositoryInterface;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use OpenApi\Attributes as OA;

class CommentController extends Controller
{
    /**
     * Morph map for commentable types from the request.
     *
     * @var array<string, string>
     */
    private const COMMENTABLE_MAP = [
        'course' => Course::class,
        'category' => Category::class,
        'announcement' => Announcement::class,
    ];

    public function __construct(private CommentRepositoryInterface $repository) {}

    #[OA\Get(
        path: '/api/v1/comments/{type}/{id}',
        summary: 'Onaylı yorumları getir',
        tags: ['Comments'],
        parameters: [
            new OA\Parameter(name: 'type', in: 'path', required: true, schema: new OA\Schema(type: 'string', enum: ['course', 'category', 'announcement'])),
            new OA\Parameter(name: 'id', in: 'path', required: true, schema: new OA\Schema(type: 'integer')),
        ],
        responses: [
            new OA\Response(response: 200, description: 'Onaylı yorum listesi'),
            new OA\Response(response: 404, description: 'Geçersiz yorum tipi'),
        ],
    )]
    public function index(string $type, int $id): AnonymousResourceCollection|JsonResponse
    {
        $commentableType = self::COMMENTABLE_MAP[$type] ?? null;

        if ($commentableType === null) {
            return response()->json(['message' => 'Geçersiz yorum tipi.'], 404);
        }

        $comments = $this->repository->getApprovedByCommentable($commentableType, $id);

        return CommentResource::collection($comments);
    }

    #[OA\Post(
        path: '/api/v1/comments',
        summary: 'Yorum gönder',
        tags: ['Comments'],
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\JsonContent(
                required: ['body', 'author_name', 'author_email', 'commentable_type', 'commentable_id'],
                properties: [
                    new OA\Property(property: 'body', type: 'string'),
                    new OA\Property(property: 'author_name', type: 'string'),
                    new OA\Property(property: 'author_email', type: 'string', format: 'email'),
                    new OA\Property(property: 'commentable_type', type: 'string', enum: ['course', 'category', 'announcement']),
                    new OA\Property(property: 'commentable_id', type: 'integer'),
                    new OA\Property(property: 'rating', type: 'integer', minimum: 1, maximum: 5),
                ],
            ),
        ),
        responses: [
            new OA\Response(response: 201, description: 'Yorum gönderildi'),
            new OA\Response(response: 422, description: 'Validasyon hatası'),
        ],
    )]
    public function store(StoreCommentRequest $request, CreateCommentAction $action): JsonResponse
    {
        $validated = $request->validated();
        $validated['commentable_type'] = self::COMMENTABLE_MAP[$validated['commentable_type']] ?? $validated['commentable_type'];

        $dto = CommentData::fromArray($validated);
        $action->execute($dto);

        return response()->json(['message' => 'Yorumunuz incelenmek üzere gönderildi.'], 201);
    }
}
