<?php

namespace KupShop\CDNBundle;

use KupShop\CDNBundle\Exception\CDNException;
use KupShop\KupShopBundle\Util\System\UrlFinder;
use Psr\Log\LoggerInterface;

class CDN
{
    protected $cdn_domain;

    protected $cdn_zone_id;

    protected $cdn_token;

    protected $stream_domain;

    protected $stream_library_id;

    protected $stream_token;

    /** @var UrlFinder */
    protected $urlFinder;

    /** @var LoggerInterface */
    protected $logger;

    public const accountKey = '1cfc3971-2fa2-4110-907a-43e6edf74e6cedbf97b2-bfb8-421c-8911-a2835f1837d2';

    public function __construct()
    {
        $settings = \Settings::getDefault();
        $success = true;

        if ($settings['cdn']['url'] ?? $success = false) {
            $this->cdn_domain = $settings['cdn']['url'];
        }
        if ($settings['cdn']['zoneId'] ?? $success = false) {
            $this->cdn_zone_id = $settings['cdn']['zoneId'];
        }

        if (findModule(\Modules::VIDEOS)) {
            if ($settings['stream']['url'] ?? $success = false) {
                $this->stream_domain = $settings['stream']['url'];
            }
            if ($settings['stream']['libraryId'] ?? $success = false) {
                $this->stream_library_id = $settings['stream']['libraryId'];
            }
            if ($settings['stream']['apiKey'] ?? $success = false) {
                $this->stream_token = $settings['stream']['apiKey'];
            }
        }

        //        if (!$success) {
        //            throw new CDNException('Nejsou nastavena všechna potřebná data');
        //        }
    }

    /**
     * @required
     */
    public function setLogger(LoggerInterface $logger): void
    {
        $this->logger = $logger;
    }

    protected function curl_init($url, $token, $type = 'POST')
    {
        $curl = curl_init();

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $type);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: text/json', "AccessKey:{$token}"]);

        return $curl;
    }

    /**
     * POST helper method.
     */
    protected function post($url, $data, $token)
    {
        $this->logger->notice('CDN post Request', [
            'url' => $url,
            'data' => $data,
        ]);
        $curl = $this->curl_init($url, $token);

        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));

        $output = curl_exec($curl);
        curl_close($curl);
        $this->logger->notice('CDN post Response', [
            'url' => $url,
            'data' => $data,
            'response' => $output,
        ]);

        return json_decode($output, true);
    }

    /**
     * GET helper method.
     */
    protected function get($url, $token)
    {
        $curl = $this->curl_init($url, $token, 'GET');

        $output = curl_exec($curl);
        curl_close($curl);

        return json_decode($output, true);
    }

    /**
     * DELETE helper method.
     */
    protected function delete($url, $data, $token)
    {
        $curl = $this->curl_init($url, $token, 'DELETE');

        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));

        $output = curl_exec($curl);
        curl_close($curl);

        return json_decode($output, true);
    }

    /**
     * Returns thumbnail url.
     *
     * @var string Video CDN ID
     *
     * @return string url
     */
    public function getThumbnail($id): array
    {
        $filename = $this->getVideoInfo($id)['thumbnailFileName'];

        return [
            'filename' => $filename,
            'url' => "https://{$this->stream_domain}/{$id}/{$filename}",
        ];
    }

    /**
     * Returns info about video.
     *
     * @param $id string Video CDN ID
     */
    public function getVideoInfo($id)
    {
        return $this->get("https://video.bunnycdn.com/library/{$this->stream_library_id}/videos/{$id}", $this->stream_token);
    }

    /**
     * Returns mp4 url in given resolution.
     *
     * @param string $quantity
     *
     * @return string mp4 url
     */
    public function getMP4Video($id, $quantity = '240p')
    {
        return 'https://'.$this->stream_domain."/{$id}/play_{$quantity}.mp4";
    }

    /**
     * Returns HLS url in given resolution.
     *
     * @return string HLS url
     */
    public function getHLSPlaylist($id): string
    {
        return "https://{$this->stream_domain}/{$id}/playlist.m3u8";
    }

    /**
     * Returns mp4 url in given resolution.
     *
     * @return string iframe url
     */
    public function getIframeUrl($id, $autoplay): string
    {
        $autoplay = $autoplay ? 'true' : 'false';

        return "https://iframe.mediadelivery.net/embed/{$this->stream_library_id}/{$id}?autoplay={$autoplay}";
    }

    /**
     * Create video on cdn.
     *
     * @param null $title
     * @param null $collectionId
     */
    public function createVideo($title = null, $collectionId = null)
    {
        if (!$title) {
            $title = date('Y-m-d H:i:s');
        }

        return $this->post("https://video.bunnycdn.com/library/{$this->stream_library_id}/videos", ['title' => $title, 'collectionId' => $collectionId], $this->stream_token);
    }

    /**
     * Fetch video from eshop to cdn.
     */
    public function fetchVideo($videoId, $url)
    {
        return $this->post("https://video.bunnycdn.com/library/{$this->stream_library_id}/videos/{$videoId}/fetch", ['url' => $url], $this->stream_token);
    }

    public function deleteVideo($videoId)
    {
        return $this->delete("https://video.bunnycdn.com/library/{$this->stream_library_id}/videos/{$videoId}", [], $this->stream_token);
    }

    public function setStreamWebhook($url)
    {
        $output = $this->post("https://api.bunny.net/videolibrary/{$this->stream_library_id}", ['WebhookUrl' => $url], self::accountKey);
    }
}
