<?php

declare(strict_types=1);

namespace App\Http\Controllers\Project;

use App\Http\Controllers\Concerns\AuthorizesProjectAccess;
use App\Http\Controllers\Controller;
use App\Http\Requests\Comment\StoreCommentRequest;
use App\Http\Resources\CommentResource;
use App\Models\Comment;
use App\Models\MediaItem;
use App\Models\Project;
use App\Support\ApiResponse;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class ProjectCommentController extends Controller
{
    use AuthorizesProjectAccess;

    public function index(Request $request, Project $project)
    {
        $this->authorizeProjectAccess($project);

        $query = Comment::query()
            ->with('user')
            ->where(function ($scope) use ($project): void {
                $scope->where(function ($projectComments) use ($project): void {
                    $projectComments->where('commentable_type', Project::class)
                        ->where('commentable_id', $project->id);
                })->orWhereHasMorph(
                    'commentable',
                    [MediaItem::class],
                    fn ($mediaQuery) => $mediaQuery->where('project_id', $project->id)
                );
            })
            ->latest();

        $perPage = min($request->integer('per_page', 15), 50);

        return CommentResource::collection(
            $request->boolean('noPaginate') ? $query->get() : $query->paginate($perPage)
        );
    }

    public function store(StoreCommentRequest $request, Project $project)
    {
        $this->authorizeProjectAccess($project);

        try {
            DB::beginTransaction();

            if ($request->filled('media_item_id')) {
                $mediaItem = MediaItem::query()
                    ->where('project_id', $project->id)
                    ->findOrFail($request->integer('media_item_id'));

                $commentableType = MediaItem::class;
                $commentableId = $mediaItem->id;
            } else {
                $commentableType = Project::class;
                $commentableId = $project->id;
            }

            $comment = Comment::create([
                'user_id' => Auth::id(),
                'commentable_type' => $commentableType,
                'commentable_id' => $commentableId,
                'parent_id' => $request->input('parent_id'),
                'body' => $request->string('body'),
                'status' => Comment::STATUS_APPROVED,
            ]);

            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();

            return ApiResponse::response(message: $exception->getMessage(), status: 419);
        }

        return new CommentResource($comment->load('user'));
    }
}
