<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Models\Collection;
use App\Services\CollectionFollowService;
use App\Services\CollectionLikeService;
use App\Services\CollectionSaveService;
use App\Services\CollectionService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class CollectionEngagementController extends Controller
{
    public function __construct(
        private readonly CollectionLikeService $likes,
        private readonly CollectionFollowService $follows,
        private readonly CollectionSaveService $saves,
        private readonly CollectionService $collections,
    ) {
    }

    public function like(Request $request, Collection $collection): JsonResponse
    {
        abort_unless($collection->isPubliclyEngageable(), 404);

        $this->likes->like($request->user(), $collection);

        return response()->json([
            'ok' => true,
            'liked' => true,
            'likes_count' => (int) $collection->fresh()->likes_count,
        ]);
    }

    public function unlike(Request $request, Collection $collection): JsonResponse
    {
        abort_unless($collection->isPubliclyEngageable(), 404);

        $this->likes->unlike($request->user(), $collection);

        return response()->json([
            'ok' => true,
            'liked' => false,
            'likes_count' => (int) $collection->fresh()->likes_count,
        ]);
    }

    public function follow(Request $request, Collection $collection): JsonResponse
    {
        abort_unless($collection->isPubliclyEngageable(), 404);

        $this->follows->follow($request->user(), $collection);

        return response()->json([
            'ok' => true,
            'following' => true,
            'followers_count' => (int) $collection->fresh()->followers_count,
        ]);
    }

    public function unfollow(Request $request, Collection $collection): JsonResponse
    {
        abort_unless($collection->isPubliclyEngageable(), 404);

        $this->follows->unfollow($request->user(), $collection);

        return response()->json([
            'ok' => true,
            'following' => false,
            'followers_count' => (int) $collection->fresh()->followers_count,
        ]);
    }

    public function share(Request $request, Collection $collection): JsonResponse
    {
        abort_unless($collection->isPubliclyEngageable(), 404);

        $collection = $this->collections->recordShare($collection, $request->user());

        return response()->json([
            'ok' => true,
            'shares_count' => (int) $collection->shares_count,
        ]);
    }

    public function save(Request $request, Collection $collection): JsonResponse
    {
        $payload = $request->validate([
            'context' => ['nullable', 'string', 'max:80'],
            'context_meta' => ['nullable', 'array'],
        ]);

        $this->saves->save(
            $request->user(),
            $collection,
            isset($payload['context']) ? (string) $payload['context'] : null,
            (array) ($payload['context_meta'] ?? []),
        );

        return response()->json([
            'ok' => true,
            'saved' => true,
            'saves_count' => (int) $collection->fresh()->saves_count,
        ]);
    }

    public function unsave(Request $request, Collection $collection): JsonResponse
    {
        $this->saves->unsave($request->user(), $collection);

        return response()->json([
            'ok' => true,
            'saved' => false,
            'saves_count' => (int) $collection->fresh()->saves_count,
        ]);
    }
}
