<?php
declare(strict_types=1);
namespace Slivki\Response\Beauty\Offer\Factory;
use Slivki\Dao\Category\Rating\DirectorRatingDaoInterface;
use Slivki\Entity\BeautyMaster;
use Slivki\Entity\Category;
use Slivki\Entity\Director;
use Slivki\Enum\Beauty\MasterWorkPlaceType;
use Slivki\Response\Beauty\Offer\MasterLocationResponse;
use Slivki\Response\Beauty\Offer\MasterResponse;
use Slivki\Response\OnlineOrder\Director\DirectorResponse;
use Slivki\Services\ImageService;
use function array_map;
use function array_values;
use function implode;
use function round;
final class MasterResponseFactory
{
private ImageService $imageService;
private DirectorRatingDaoInterface $directorRatingDao;
private ?array $ratingDirectors = null;
public function __construct(ImageService $imageService, DirectorRatingDaoInterface $directorRatingDao)
{
$this->imageService = $imageService;
$this->directorRatingDao = $directorRatingDao;
}
public function create(BeautyMaster $beautyMaster): MasterResponse
{
return $this->createResponse($beautyMaster, 0);
}
public function createForCategory(BeautyMaster $beautyMaster, int $categoryId): MasterResponse
{
return $this->createResponse(
$beautyMaster,
$this->getRating($categoryId, $beautyMaster->getDirector()),
);
}
private function createResponse(BeautyMaster $beautyMaster, float $rating): MasterResponse
{
$director = $beautyMaster->getDirector();
$locations = [];
$offerIds = [];
foreach ($beautyMaster->getLocations() as $location) {
$locations[] = new MasterLocationResponse(
$location->getId(),
implode(', ', [$location->getCity(), $location->getStreet(), $location->getHouse()]),
);
$locationId = $location->firstOffer()->getID();
$offerIds[$locationId] = $locationId;
}
return new MasterResponse(
$beautyMaster->getId(),
MasterWorkPlaceType::getByStatus($beautyMaster->getStatus()),
$beautyMaster->getFirstName(),
$beautyMaster->getLastName(),
$this->imageService->getImageURLCachedWithDomain($beautyMaster->getPhoto(), 0, 0),
$rating,
$beautyMaster->getDescription(),
$locations,
array_map(static fn (Category $tag) => $tag->getName(), $beautyMaster->getTags()->toArray()),
array_values($offerIds),
$director !== null
? new DirectorResponse(
$director->getID(),
$this->imageService->getImageURLCachedWithDomain($director->getOnlinePaymentLogo(), 0, 0),
$director->getName(),
$director->getLegalEntity(),
$director->getTaxID(),
)
: null,
);
}
private function getRating(int $categoryId, ?Director $director): float
{
if ($director === null) {
return 0;
}
if ($this->ratingDirectors === null) {
$this->ratingDirectors = $this->directorRatingDao->findDirectorRatingByCategoryId($categoryId);
}
foreach ($this->ratingDirectors as $ratingDirector) {
if ($ratingDirector->getDirectorId() === $director->getID()) {
return round($ratingDirector->getAvgCommentRating(), 2);
}
}
return 0;
}
}