toggleSimple( request: $request, table: 'user_favorites', keyColumns: ['user_id', 'artwork_id'], keyValues: ['user_id' => (int) $request->user()->id, 'artwork_id' => $artworkId], insertPayload: ['created_at' => now()], requiredTable: 'user_favorites' ); $this->syncArtworkStats($artworkId); return response()->json($this->statusPayload((int) $request->user()->id, $artworkId)); } public function like(Request $request, int $artworkId): JsonResponse { $this->toggleSimple( request: $request, table: 'artwork_likes', keyColumns: ['user_id', 'artwork_id'], keyValues: ['user_id' => (int) $request->user()->id, 'artwork_id' => $artworkId], insertPayload: ['created_at' => now(), 'updated_at' => now()], requiredTable: 'artwork_likes' ); $this->syncArtworkStats($artworkId); return response()->json($this->statusPayload((int) $request->user()->id, $artworkId)); } public function report(Request $request, int $artworkId): JsonResponse { if (! Schema::hasTable('artwork_reports')) { return response()->json(['message' => 'Reporting unavailable'], 422); } $data = $request->validate([ 'reason' => ['nullable', 'string', 'max:1000'], ]); DB::table('artwork_reports')->updateOrInsert( [ 'artwork_id' => $artworkId, 'reporter_user_id' => (int) $request->user()->id, ], [ 'reason' => trim((string) ($data['reason'] ?? '')) ?: null, 'reported_at' => now(), 'created_at' => now(), 'updated_at' => now(), ] ); return response()->json(['ok' => true, 'reported' => true]); } public function follow(Request $request, int $userId): JsonResponse { if (! Schema::hasTable('friends_list')) { return response()->json(['message' => 'Follow unavailable'], 422); } $actorId = (int) $request->user()->id; if ($actorId === $userId) { return response()->json(['message' => 'Cannot follow yourself'], 422); } $state = $request->boolean('state', true); $query = DB::table('friends_list') ->where('user_id', $actorId) ->where('friend_id', $userId); if ($state) { if (! $query->exists()) { DB::table('friends_list')->insert([ 'user_id' => $actorId, 'friend_id' => $userId, 'date_added' => now(), ]); } } else { $query->delete(); } $followersCount = (int) DB::table('friends_list') ->where('friend_id', $userId) ->count(); return response()->json([ 'ok' => true, 'is_following' => $state, 'followers_count' => $followersCount, ]); } private function toggleSimple( Request $request, string $table, array $keyColumns, array $keyValues, array $insertPayload, string $requiredTable ): void { if (! Schema::hasTable($requiredTable)) { abort(422, 'Interaction unavailable'); } $state = $request->boolean('state', true); $query = DB::table($table); foreach ($keyColumns as $column) { $query->where($column, $keyValues[$column]); } if ($state) { if (! $query->exists()) { DB::table($table)->insert(array_merge($keyValues, $insertPayload)); } } else { $query->delete(); } } private function syncArtworkStats(int $artworkId): void { if (! Schema::hasTable('artwork_stats')) { return; } $favorites = Schema::hasTable('user_favorites') ? (int) DB::table('user_favorites')->where('artwork_id', $artworkId)->count() : 0; $likes = Schema::hasTable('artwork_likes') ? (int) DB::table('artwork_likes')->where('artwork_id', $artworkId)->count() : 0; DB::table('artwork_stats')->updateOrInsert( ['artwork_id' => $artworkId], [ 'favorites' => $favorites, 'rating_count' => $likes, 'updated_at' => now(), ] ); } private function statusPayload(int $viewerId, int $artworkId): array { $isFavorited = Schema::hasTable('user_favorites') ? DB::table('user_favorites')->where('user_id', $viewerId)->where('artwork_id', $artworkId)->exists() : false; $isLiked = Schema::hasTable('artwork_likes') ? DB::table('artwork_likes')->where('user_id', $viewerId)->where('artwork_id', $artworkId)->exists() : false; $favorites = Schema::hasTable('user_favorites') ? (int) DB::table('user_favorites')->where('artwork_id', $artworkId)->count() : 0; $likes = Schema::hasTable('artwork_likes') ? (int) DB::table('artwork_likes')->where('artwork_id', $artworkId)->count() : 0; return [ 'ok' => true, 'is_favorited' => $isFavorited, 'is_liked' => $isLiked, 'stats' => [ 'favorites' => $favorites, 'likes' => $likes, ], ]; } }