<?php
/**
 * @author Colinet Julien
 */

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

use CpCreation\VitiCore\Bridge\Symfony\Bundle\Client\FacebookClient;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Utils\Mailer;
use CpCreation\VitiCore\SocialNetwork\Model\SocialNetwork;
use CpCreation\VitiCore\SocialNetwork\Repository\SocialNetworkRepository;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Client\ConnectCpCreationClient;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\CacheItem;

class FacebookInstagramProvider implements SocialNetworkProviderInterface
{
    const TYPE = 'facebook_instagram';

    /**
     * @var FacebookClient
     */
    private $client;

    /**
     * @var CacheItem
     */
    private $cache;

    /**
     * @var string
     */
    private $accessToken;

    /**
     * @var string
     */
    private $instagramId;

    /**
     * @var SocialNetworkRepository
     */
    private $socialNetworkRepository;

    /**
     * @var SocialNetwork|null|object
     */
    private $social;

    /**
     * @var Mailer
     */
    private $mailer;

    public function __construct(SocialNetworkRepository $socialNetworkRepository,
        FacebookClient $client,
        ConnectCpCreationClient $cpCreationClient,
        AdapterInterface $cache,
        Mailer $mailer
    ) {
        $this->accessToken             = '';
        $this->instagramId             = '';
        $social                        = $socialNetworkRepository->findOneBy(['network' => static::TYPE]);
        $this->socialNetworkRepository = $socialNetworkRepository;
        $this->cache                   = $cache;
        $this->client                  = $client;
        $this->mailer                  = $mailer;
        if (!$social) {
            return;
        }
        $this->social = $social;
        $news         = $cache->getItem('news.facebook_instagram');
        if (!$news->isHit()) {
            try {
                $response          = $cpCreationClient->get('api/client_socials/'.$social->getConfiguration()['id']);
                $result            = json_decode($response->getBody()->getContents(), true);
                $this->accessToken = $result['token'];
                $this->instagramId = $this->social->getConfiguration()['accountInstagram'];

            } catch (\Exception $e) {
                $mailer->sendErrorConnexionApiConnectSocialInstagram($e->getMessage());
            }

        }

    }

    /**
     * @param $count
     * @return mixed|\Psr\Http\Message\ResponseInterface
     * @throws \Doctrine\ORM\NonUniqueResultException
     */
    public function getMedias($count)
    {
        $news = $this->cache->getItem('news.facebook_instagram');
        if (!$news->isHit()) {
            try {
                // Returns a `Facebook\FacebookResponse` object
                $response = $this->client->get(
                    '/'.$this->instagramId.'/media?fields=media_url,media_type,thumbnail_url,timestamp,caption,ig_id,video_url,permalink&transport=cors&access_token='.$this->accessToken.'&limit='.$count
                );

                $response = json_decode($response->getBody());
                $news->expiresAfter(60);
                $this->social->setData($response->data);
                $this->socialNetworkRepository->save($this->social);
                $this->cache->save($news->set($response));

                return $response;

            } catch (\Exception $e) {
                $this->mailer->sendErrorInstagram('Facebook Instagram : '.$e->getMessage());
            }

        }

        return $news->get();

    }

    /**
     * @param     $token
     * @param int $count
     * @return mixed
     */
    public function getMediasNext($token, $count = 12)
    {
        try {
            // Returns a `Facebook\FacebookResponse` object
            $response = $this->client->get(
                '/'.$this->instagramId.'/media?fields=media_url,media_type,thumbnail_url,timestamp,caption,ig_id,video_url,permalink&transport=cors&access_token='.$this->accessToken.'&&limit='.$count.'&after='.$token
            );
            $response = json_decode($response->getBody(), true);

            return json_decode($response->getBody(), true);

        } catch (\Exception $e) {
            echo 'Graph returned an error: '.$e->getMessage();
        }

        return [];
    }

    /**
     * @param     $token
     * @param int $count
     * @return mixed
     */
    public function getMediasBefore($token, $count = 12)
    {
        try {
            // Returns a `Facebook\FacebookResponse` object
            $response = $this->client->get(
                '/'.$this->instagramId.'/media?fields=media_url,media_type,thumbnail_url,timestamp,caption,ig_id,video_url,permalink&transport=cors&access_token='.$this->accessToken.'&&limit='.$count.'&before='.$token
            );
            $response = json_decode($response->getBody(), true);

            return json_decode($response->getBody(), true);

        } catch (\Exception $e) {
            echo 'Graph returned an error: '.$e->getMessage();
        }

        return [];
    }

    /**
     * @return string
     */
    public function getNetwork(): string
    {
        return static::TYPE;
    }
}