<?php

declare(strict_types=1);

/*
 * This file is part of the VitiCore 2.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\Provider\SocialNetwork;

use CpCreation\VitiCore\Bridge\Symfony\Bundle\Client\InstagramClient;
use CpCreation\VitiCore\SocialNetwork\Model\SocialNetwork;
use CpCreation\VitiCore\SocialNetwork\Repository\SocialNetworkRepository;
use Psr\Cache\CacheItemPoolInterface;

class InstagramProvider implements SocialNetworkProviderInterface
{
    public const TYPE = 'instagram';

    private string $accessToken = '';
    private ?SocialNetwork $social = null;

    public function __construct(
        private SocialNetworkRepository $socialNetworkRepository,
        private InstagramClient $client,
        private CacheItemPoolInterface $cache,
    ) {
        /** @var SocialNetwork|null $social */
        $social = $this->socialNetworkRepository->findOneBy([
            'network' => self::TYPE,
        ]);

        $this->social = $social;

        if (null === $social) {
            return;
        }

        $token = $social->getToken();

        if (\is_string($token) && '' !== $token) {
            $this->accessToken = $token;
        }
    }

    public function getMedias(int $count): array
    {
        if (null === $this->social || '' === $this->accessToken) {
            return [];
        }

        $cacheItem = $this->cache->getItem('news.instagram');

        if ($cacheItem->isHit()) {
            $cached = $cacheItem->get();

            return \is_array($cached) ? $cached : [];
        }

        try {
            $result = $this->client->get(
                'users/self/media/recent',
                [
                    'query' => [
                        'access_token' => $this->accessToken,
                        'count' => $count,
                    ],
                ]
            );

            /** @var array{data?: array} $response */
            $response = json_decode(
                $result->getBody()->getContents(),
                true,
                512,
                \JSON_THROW_ON_ERROR
            );

            $medias = isset($response['data']) && \is_array($response['data'])
                ? $response['data']
                : [];

            $cacheItem->expiresAfter(60);
            $cacheItem->set($medias);
            $this->cache->save($cacheItem);

            $this->social->setData($medias);
            $this->socialNetworkRepository->save($this->social);

            return $medias;
        } catch (\Throwable) {
            return [];
        }
    }

    public function getNetwork(): string
    {
        return self::TYPE;
    }
}
