<?php
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    Aman Srivastava <aman.srivastava462@webkul.com>
 * @copyright 2017 Webkul Software Pvt. Ltd. (http://www.webkul.com)
 */

class ProductNormalizer extends \ExternelApiBaseProductNormalizer implements NormalizerInterface
{
    /** @var NormalizerInterface */
    protected $productNormalizer;

    /** @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($product, $format = null, array $context = [])
    {
        $productStandard = $this->productNormalizer->normalize($product, 'standard', $context);
        $identifier = $this->attributeRepository->getIdentifierCode();

        if (isset($productStandard['values'][$identifier])) {
            unset($productStandard['values'][$identifier]);
        }

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

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

        if (empty($productStandard['associations'])) {
            $productStandard['associations'] = (object) $productStandard['associations'];
        }

        return $productStandard;
    }

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

    /**
     * @param array  $values
     *
     * @return array
     */
    protected function addDownloadLink(array $values)
    {
        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;
    }
}
