<?php

use Joomla\CMS\Event\QuickIcon\GetIconEvent;
use Joomla\CMS\Factory;
use Joomla\CMS\Filesystem\Folder;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Uri\Uri;

defined('_JEXEC') or die('Restricted access');

class PlgSystemJasocialshare extends CMSPlugin
{
    public static $services = [
        'facebook',
        'messenger',
        'linkedin',
        'tumblr',
        'whatsapp',
        'twitter',
        'reddit',
        'telegram',
        'line',
        'livejournal',
        'flipboard',
        'instapaper',
        'getpocket',
        'hackernew',
        'kooapp',
        'yahoo',
        'email',
    ];

    protected $icons = [];

    public function onAfterInitialise()
    {
        $app = Factory::getApplication();
        $isAdmin = $app->isClient('administrator');
        if ($isAdmin) {
            return;
        }

        $input = $app->input;
        
        $jashare = $input->get('jasocialshare');
        $service = $input->get('service');
        $appid = $this->params->get('fb_app_id');
        $currentHost = Uri::getInstance()->getHost();

        if (!$jashare) {
            return;
        }

        // TODO: validate url before store to database
        $url = $this->validateUrl($input->getString('url'));

        if ($url && in_array($service, self::$services)) {
            switch ($service) {
                case 'facebook':
                    $api = 'https://www.facebook.com/sharer/sharer.php?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button&u=';
                    $target = $api . urlencode($url) . '&timer=' . time();
                    break;
                case 'messenger':
                    $api = 'https://www.facebook.com/dialog/send?kid_directed_site=0&sdk=joey&ref=plugin&src=share_button&link=';
                    $target = $api . urlencode($url) . '&app_id=' . urlencode($appid) . '&redirect_uri=' . urlencode($currentHost) . '&timer=' . time();
                    break;
                case 'linkedin':
                    $api = 'https://www.linkedin.com/shareArticle?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button&mini=true&url=';
                    $target = $api . urlencode($url) . '&timer=' . time();
                    break;
                case 'tumblr':
                    $api = 'https://www.tumblr.com/share/link?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button&url=';
                    $target = $api . urlencode($url) . '&timer=' . time();
                    break;
                case 'whatsapp':
                    $api = 'https://api.whatsapp.com/send?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button&text=';
                    $target = $api . urlencode($url) . '&timer=' . time();
                    break;
                case 'twitter':
                    $api = 'https://twitter.com/intent/tweet?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button&url=';
                    $target = $api . urlencode($url) . '&sender_device=pc&text=' . '&timer=' . time();
                    break;
                case 'reddit':
                    $api = 'https://reddit.com/submit?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button&url=';
                    $target = $api . urlencode($url) . '&title=' . '&timer=' . time();
                    break; 
                case 'telegram':
                    $api = 'https://t.me/share/url?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button&url=';
                    $target = $api . urlencode($url) . '&text=' . '&timer=' . time();
                    break;
                case 'line':
                    $api = 'https://social-plugins.line.me/lineit/share?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button&url=';
                    $target = $api . urlencode($url) . '&timer=' . time();
                    break;
                case 'livejournal':
                    $api = 'http://www.livejournal.com/update.bml?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button';
                    $target = $api . '&subject=' . '&event=' . urlencode($url) . '&timer=' . time();
                    break;
                case 'flipboard':
                    $api = 'https://share.flipboard.com/bookmarklet/popout?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button&v=2&title=&url=';
                    $target = $api . urlencode($url) . '&timer=' . time();
                    break;
                case 'instapaper':
                    $api = 'https://www.instapaper.com/edit?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button&url=';
                    $target = $api . urlencode($url) . '&title=' . '&description=' . '&timer=' . time();
                    break;
                case 'getpocket':
                    $api = 'https://getpocket.com/edit?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button&url=';
                    $target = $api . urlencode($url) . '&timer=' . time();
                    break;
                case 'hackernew':
                    $api = 'https://news.ycombinator.com/submitlink?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button&u=';
                    $target = $api . urlencode($url) . '&t=' . '&timer=' . time();
                    break;
                case 'kooapp':
                    $api = 'https://www.kooapp.com/create?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button&title=';
                    $target = $api . urlencode($url) . '&link=' . '&timer=' . time();
                    break;
                case 'yahoo':
                    $api = 'http://compose.mail.yahoo.com/?kid_directed_site=0&sdk=joey&display=popup&ref=plugin&src=share_button&to=';
                    $target = $api . '&subject=' . '&body=' . urlencode($url) . '&timer=' . time();
                    break;
            }
            if (isset($target)) {
                $this->updateCountShare($url, $service);
                header('Location: ' . $target);
                die;
            }
        }
    }

    public function onBeforeRender()
    {
        $isAdmin = Factory::getApplication()->isClient('administrator');
        if ($isAdmin) {
            return;
        }

        $excludedElements = $this->params->get('excluded_elements', '');
        $selectors = array_filter(array_map('trim', explode(PHP_EOL, $excludedElements)));

        // exclude render buttons on mod_articles_news
        $selectors[] = '.mod-articlesnews-horizontal';

        $doc = Factory::getDocument();
        $doc->addScriptOptions('ja-share-excluded', $selectors);

        HTMLHelper::_('behavior.core');
        HTMLHelper::script('plugins/system/jasocialshare/assets/jasocialshare.js');
        HTMLHelper::stylesheet('plugins/system/jasocialshare/assets/style.css');

        $lang = Factory::getApplication()->getLanguage();
        $lang->load('plg_system_jasocialshare', JPATH_ADMINISTRATOR);
        Text::script('JASOCIALSHARE_EMAIL_SUBJECT');
    }

    public function onContentAfterTitle($context, $item, $params)
    {
        $events = $this->params->get('plugin_events', []);
        if (!in_array('onContentAfterTitle', $events)) {
            return;
        }

        $supportedContexts = $this->params->get('supported_contexts', []);
        if (!in_array($context, $supportedContexts)) {
            return;
        }

        return $this->renderShortcode();
    }

    public function onContentBeforeDisplay($context, $item, $params)
    {
        $events = $this->params->get('plugin_events', []);
        if (!in_array('onContentBeforeDisplay', $events)) {
            return;
        }

        $supportedContexts = $this->params->get('supported_contexts', []);
        if (!in_array($context, $supportedContexts)) {
            return;
        }

        return $this->renderShortcode();
    }

    public function onContentAfterDisplay($context, $item, $params)
    {
        $events = $this->params->get('plugin_events', []);
        if (!in_array('onContentAfterDisplay', $events)) {
            return;
        }

        $supportedContexts = $this->params->get('supported_contexts', []);
        if (!in_array($context, $supportedContexts)) {
            return;
        }

        return $this->renderShortcode();
    }

    public function onAjaxJasocialshare()
    {
        $input = Factory::getApplication()->input;
        $task = $input->get('ja_ajax_task');

        if ($task === 'renderButtons') {
            return $this->renderButtons();
        }

        return false;
    }

    public function renderButtons()
    {
        $input = Factory::getApplication()->input;
        $url = $this->validateUrl($input->getString('url', ''));

        if (!$url) {
            return '';
        }

        $lang = Factory::getApplication()->getLanguage();
        $lang->load('plg_system_jasocialshare', JPATH_ADMINISTRATOR);

        $serviceTags = $input->getString('services', '');
        $services = array_filter(explode(',', $serviceTags), function ($tag) {
            return in_array($tag, self::$services);
        });

        if (!$services) {
            $services = $this->params->get('services', []) ?: self::$services;
        }

        $layout = $input->get('layout', 'default');

        $buttons = $this->getButtons($url, $services);
        $params = $this->params;
        $showCount = $input->get('showcount', $params->get('show_count', 1));
        $textTotal = '';
        if ($showCount) {
            $sub = $this->getUrlSub($url);
            $db = Factory::getDbo();
            $query = "SELECT SUM(hit) FROM `#__jasocialshare_stats` WHERE `url` = " . $db->q($sub);
            $total = (int) $db->setQuery($query)->loadResult();
            $textTotal = $total > 1 ? Text::sprintf('JASOCIALSHARE_SHARES', $total) : Text::sprintf('JASOCIALSHARE_SHARE', $total);
        }

        $showText = $input->get('showtext', $params->get('show_service_text', 1));
        $buttonSize = $input->get('buttonsize', $params->get('button_size', 'medium'));
        $buttonStyle = $input->get('buttonstyle', $params->get('button_style', 'square'));

        $path = PluginHelper::getLayoutPath('system', 'jasocialshare', $layout);
        ob_start();
        include $path;
        $content = ob_get_clean();

        return $content;
    }

    protected function renderShortcode()
    {
        return '<div class="ja-share-button" layout="default" ></div>';
    }

    protected function updateCountShare($url, $service)
    {
        $sub = $this->getUrlSub($url);
        $db = Factory::getDbo();
        $query = $db->getQuery(true)
            ->select('id')
            ->from($db->qn('#__jasocialshare_stats'))
            ->where($db->qn('service') . ' = ' . $db->q($service))
            ->where($db->qn('url') . ' = ' . $db->q($sub));

        $id = $db->setQuery($query)->loadResult();

        if ($id) {
            $query = $db->getQuery(true)
                ->update('#__jasocialshare_stats')
                ->set([
                    'hit = hit + 1',
                ])
                ->where($db->qn('id') . ' = ' . $db->q($id));
            $db->setQuery($query)->execute();
        } else {
            $data = (object) [
                'service' => $service,
                'url' => $sub,
                'hit' => 1,
            ];
            $db->insertObject('#__jasocialshare_stats', $data, 'id');
        }
    }

    protected function getUrlSub($url)
    {
        $root = Uri::root();
        $uri = Uri::getInstance($url);
        $clean = $uri->toString(['scheme', 'host', 'port', 'path']);
        $sub = str_replace($root, '', $clean);

        return '/' . $sub;
    }

    protected function validateUrl($url)
    {
        if (!$url) {
            return false;
        }

        if (!filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED)) {
            return false;
        }

        if (!Uri::isInternal($url)) {
            return false;
        }

        return $url;
    }

    protected function getButtons($url, $services)
    {
        $buttons = [];
        foreach ($services as $service) {
            $buttons[] = [
                'url' => Uri::root() . 'index.php?jasocialshare=1&service=' . $service . '&url=' . urlencode($url),
                'service' => $service,
            ];
        }

        return $buttons;
    }

    protected function getIcon($service)
    {
        if (!$this->icons) {
            $path = JPATH_PLUGINS . '/system/jasocialshare/assets/svg/';
            $files = Folder::files($path, '.', false, true);

            foreach ($files as $file) {
                $info = pathinfo($file);
                $this->icons[$info['filename']] = file_get_contents($file);
            }
        }

        return isset($this->icons[$service]) ? $this->icons[$service] : '';
    }
}
