<?php
namespace App\Services;
use App\Models\Album;
use App\Models\Artist;
use App\Services\Contracts\Encyclopedia;
use App\Values\Album\AlbumInformation;
use App\Values\Artist\ArtistInformation;
use Illuminate\Support\Facades\Cache;
class EncyclopediaService
{
public function __construct(
private readonly Encyclopedia $encyclopedia,
private readonly ImageStorage $imageStorage,
private readonly SpotifyService $spotifyService,
) {
}
public function getAlbumInformation(Album $album): ?AlbumInformation
{
if ($album->is_unknown) {
return null;
}
return Cache::remember(
cache_key('album information', $album->name, $album->artist->name),
now()->addWeek(),
function () use ($album): AlbumInformation {
$info = $this->encyclopedia->getAlbumInformation($album) ?: AlbumInformation::make();
if ($album->cover || (!SpotifyService::enabled() && !$info->cover)) {
return $info;
}
$info->cover = rescue(function () use ($album, $info): ?string {
return $this->fetchAndStoreAlbumCover($album, $info) ?? $info->cover;
});
return $info;
}
);
}
public function getArtistInformation(Artist $artist): ?ArtistInformation
{
if ($artist->is_unknown || $artist->is_various) {
return null;
}
return Cache::remember(
cache_key('artist information', $artist->name),
now()->addWeek(),
function () use ($artist): ArtistInformation {
$info = $this->encyclopedia->getArtistInformation($artist) ?: ArtistInformation::make();
if ($artist->image || (!SpotifyService::enabled() && !$info->image)) {
return $info;
}
$info->image = rescue(function () use ($artist, $info): ?string {
return $this->fetchAndStoreArtistImage($artist, $info) ?? $info->image;
});
return $info;
}
);
}
private function fetchAndStoreAlbumCover(Album $album, AlbumInformation $info): ?string
{
$coverUrl = SpotifyService::enabled()
? $this->spotifyService->tryGetAlbumCover($album)
: $info->cover;
if (!$coverUrl) {
return null;
}
$fileName = $this->imageStorage->storeImage($coverUrl);
$album->cover = $fileName;
$album->save();
return image_storage_url($fileName);
}
private function fetchAndStoreArtistImage(Artist $artist, ArtistInformation $info): ?string
{
$imgUrl = SpotifyService::enabled()
? $this->spotifyService->tryGetArtistImage($artist)
: $info->image;
if (!$imgUrl) {
return null;
}
$fileName = $this->imageStorage->storeImage($imgUrl);
$artist->image = $fileName;
$artist->save();
return image_storage_url($fileName);
}
}