<?php

declare(strict_types=1);

namespace Webkul\DamBundle\Normalizer\ExternalApi;

use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Webkul\DamBundle\Services\DamServices;
use Webkul\DamBundle\Repository\AssetRepository;
use Webkul\DamBundle\Listener\ClassDefinationForCompatibility;

$versionCompatiblility = new ClassDefinationForCompatibility();
$versionCompatiblility->createClassAliases();

/**
 * @author    Alexandre Hocquard <alexandre.hocquard@akeneo.com>
 * @copyright 2018 Akeneo SAS (http://www.akeneo.com)
 * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
class ProductModelNormalizer extends \BaseProductModelNormalizer implements NormalizerInterface
{
    /** @var NormalizerInterface */
    protected $productModelNormalizer;

    /** @var \ExternelApiAttributeRepositoryInterface */
    protected $attributeRepository;

    /** @var RouterInterface */
    protected $router;
    
    /** @var AssetRepository */
    protected $assetRepository;

    /** @var DamServices */
    protected $damService;

    /**
     * @param NormalizerInterface          $productNormalizer
     * @param \ExternelApiAttributeRepositoryInterface $attributeRepository
     * @param RouterInterface              $router
     */
    public function __construct(
        NormalizerInterface $productNormalizer,
        \ExternelApiAttributeRepositoryInterface $attributeRepository,
        RouterInterface $router,
        AssetRepository $assetRepository,
        DamServices $damService
    ) {
        parent::__construct($productNormalizer, $attributeRepository, $router);
        $this->assetRepository = $assetRepository;
        $this->damService = $damService;
    }

    /**
     * {@inheritdoc}
     */
    public function normalize($productModel, $format = null, array $context = []): array
    {
        $productModelStandard = $this->productModelNormalizer->normalize($productModel, 'standard', $context);

        $mediaAttributeCodes = $this->attributeRepository->getMediaAttributeCodes();
        foreach ($productModelStandard['values'] as $attributeCode => $values) {
            // if $context['attributes'] is defined, returns only these attributes
            if (isset($context['attributes']) && !in_array($attributeCode, $context['attributes'])) {
                unset($productModelStandard['values'][$attributeCode]);
            } elseif (in_array($attributeCode, $mediaAttributeCodes)) {
                $productModelStandard['values'][$attributeCode] = $this->addDownloadLink($values);
            } elseif (in_array($attributeCode, $this->damService->getAssetAttributeCodes())) {
                $productModelStandard['values'][$attributeCode] = $this->convertAssetData($values);
            }
        }

        if (empty($productModelStandard['values'])) {
            $productModelStandard['values'] = (object) $productModelStandard['values'];
        }
        
        return $productModelStandard;
    }

    /**
     * {@inheritdoc}
     */
    public function supportsNormalization($data, $format = null): bool
    {
        return $data instanceof \ProductModelInterface && 'external_api' === $format;
    }

    /**
     * @param array $values
     *
     * @return array
     */
    protected function addDownloadLink(array $values): array
    {
        foreach ($values as $index => $value) {
            if (null !== $value['data']) {
                $route = $this->router->generate(
                    'pim_api_media_file_download',
                    ['code' => $value['data']],
                    UrlGeneratorInterface::ABSOLUTE_URL
                );
                $download = new \Link('download', $route);
                $values[$index]['_links'] = $download->toArray();
            }
        }

        return $values;
    }

    /**
     * @param array  $values
     *
     * @return array
     */
    protected function convertAssetData(array $values)
    {
        foreach ($values as $index => $value) {
            if (null !== $value['data']) {
                foreach ($value['data'] as $dataKey => $data) {
                    $values[$index]['data'][$dataKey] = $this->getAssetData($data);
                }
            }
        }

        return $values;
    }

    /**
     * @param $identifier
     *
     * @return array
     */
    public function getAssetData($identifier)
    {
        $asset = $this->assetRepository->getSingleArrayResultByCode($identifier);
        if ($asset['code']) {
            $tags = $this->damService->getRelatedTagsOfAssets($asset['code']);
            if (!empty($tags)) {
                $asset['tag'] = $tags;
            }
            $categories = $this->damService->getRelatedCategoriesOfAssets($asset['code']);
            if (!empty($categories)) {
                $asset['category'] = $categories;
            }
        }
       
        if (!$asset) {
            return new JsonResponse([], Response::HTTP_NOT_FOUND);
        }
        

        if (isset($asset['medias']) && !empty($asset['medias'])) {
            $medias = [];
            foreach ($asset['medias'] as $media) {
                $url = $this->router->generate('webkuldam_media_download', [
                                                                        'identifier' => rawurlencode($media['filePath'])
                                                                    ], UrlGeneratorInterface::ABSOLUTE_URL);
                $updatedMedia = [
                                    "filePath" => $media['filePath'],
                                    "url" => $url
                    
                                ];
                                                           
                $medias[] = $updatedMedia;
            }

            unset($asset['medias']);
            $asset['medias'] = $medias;
        }

        return $asset;
    }
}
