<?php

declare(strict_types=1);

namespace PrettyLinks\Pro\SocialButtons;

defined('ABSPATH') || exit;

use PrettyLinks\Pro\Options\Store as OptionsStore;
use PrettyLinks\Pro\PostOptions\PostOptions;
use PrettyLinks\Repositories\Links as LinksRepository;

/**
 * Pro-only social share buttons.
 *
 * Renders a bar of share links below/above post content and via the
 * `[social_buttons_bar]` shortcode. The target URL is the pretty link
 * associated with the current post (via the `_pretty-link` post meta),
 * falling back to the post
 * permalink when no pretty link is wired.
 *
 * Default network list is modernized for 2026: X (formerly Twitter),
 * Facebook, LinkedIn, Pinterest, Reddit, WhatsApp, Telegram, Email,
 * plus a Copy-Link button that uses the clipboard API. v3's Google+,
 * StumbleUpon, and Digg are dropped (defunct).
 *
 * v3 back-compat preserved at the filter boundary:
 *   - prli_social_bar_url    (the share target URL)
 *   - prli_social_bar_obj    (the raw buttons array)
 *   - prli_social_bar_html   (the final HTML)
 */
class Service
{
    /**
     * Links repository used to resolve a post's pretty link URL.
     *
     * @var LinksRepository
     */
    private LinksRepository $links;

    /**
     * Constructor.
     *
     * @param LinksRepository $links Links repository dependency.
     */
    public function __construct(LinksRepository $links)
    {
        $this->links = $links;
    }

    /**
     * Return the canonical default network button definitions.
     *
     * @return array<int, array<string, string>>
     */
    public static function defaultButtons(): array
    {
        return [
            [
                'slug'  => 'x',
                'label' => 'X',
                'url'   => 'https://x.com/intent/tweet?text={{share_message}}',
            ],
            [
                'slug'  => 'facebook',
                'label' => 'Facebook',
                'url'   => 'https://www.facebook.com/sharer/sharer.php?u={{encoded_url}}',
            ],
            [
                'slug'  => 'linkedin',
                'label' => 'LinkedIn',
                'url'   => 'https://www.linkedin.com/sharing/share-offsite/?url={{encoded_url}}',
            ],
            [
                'slug'  => 'pinterest',
                'label' => 'Pinterest',
                'url'   => 'https://www.pinterest.com/pin/create/button/?url={{encoded_url}}&description={{encoded_title}}',
            ],
            [
                'slug'  => 'reddit',
                'label' => 'Reddit',
                'url'   => 'https://www.reddit.com/submit?url={{encoded_url}}&title={{encoded_title}}',
            ],
            [
                'slug'  => 'whatsapp',
                'label' => 'WhatsApp',
                'url'   => 'https://wa.me/?text={{share_message}}',
            ],
            [
                'slug'  => 'telegram',
                'label' => 'Telegram',
                'url'   => 'https://t.me/share/url?url={{encoded_url}}&text={{encoded_title}}',
            ],
            [
                'slug'  => 'email',
                'label' => 'Email',
                'url'   => 'mailto:?subject={{encoded_title}}&body={{encoded_title}}%20{{encoded_url}}',
            ],
            [
                'slug'  => 'copy',
                'label' => 'Copy link',
                'url'   => '{{encoded_url}}',
            ],
        ];
    }

    /**
     * Normalise a stored `social_buttons` blob to the canonical v4 admin shape:
     * an ordered list of `['slug' => ..., 'enabled' => bool]`, one row per
     * network in `defaultButtons()` order.
     *
     * Bridges every legacy shape the option may hold:
     *   - v3 assoc keyed by slug: `['facebook' => ['checked' => true], ...]`
     *     (a scalar/truthy value under a slug key, e.g. `['facebook' => 1]`,
     *     is also read as that network's enabled state)
     *   - v3 `checked` flag (admin UI only reads `enabled`)
     *   - v3 `twitter` slug → v4 `x`
     *   - indexed v4 rows pass through untouched
     *
     * Slugs not in `defaultButtons()` (v3 networks v4 dropped — googleplus,
     * stumbleupon, digg) are intentionally pruned: v4 has no renderer or icon
     * for them, so their stored state is unrenderable.
     *
     * Empty input returns `[]` so the admin's first-run defaults still apply.
     * This is the single legacy-shape translator: the Pro migrator's
     * `normalise_social_buttons` step calls it once on upgrade to persist the
     * canonical shape, after which both the admin (REST read) and the
     * front-end (`resolveButtons()`) read that shape directly — no read-time
     * or runtime translation.
     *
     * @param  array<int|string, mixed> $stored The stored social_buttons blob.
     * @return array<int, array{slug: string, enabled: bool}>
     */
    public static function normaliseStoredButtons(array $stored): array
    {
        if ($stored === []) {
            return [];
        }

        $enabledBySlug = [];
        foreach ($stored as $key => $row) {
            if (is_array($row) && isset($row['slug'])) {
                $slug = (string) $row['slug'];
            } elseif (is_string($key)) {
                $slug = $key;
            } else {
                continue;
            }
            if ($slug === '') {
                continue;
            }
            if ($slug === 'twitter') {
                $slug = 'x';
            }

            if (is_array($row)) {
                $enabled = array_key_exists('enabled', $row)
                    ? !empty($row['enabled'])
                    : !empty($row['checked']);
            } else {
                $enabled = !empty($row);
            }

            // OR-merge so a present-but-off duplicate (e.g. both `x` and a
            // legacy `twitter` row) never downgrades an already-enabled slug.
            $enabledBySlug[$slug] = !empty($enabledBySlug[$slug]) || $enabled;
        }

        $out = [];
        foreach (self::defaultButtons() as $def) {
            $slug  = $def['slug'];
            $out[] = [
                'slug'    => $slug,
                'enabled' => $enabledBySlug[$slug] ?? false,
            ];
        }
        return $out;
    }

    /**
     * Register the `[social_buttons_bar]` shortcode.
     *
     * @return void
     */
    public function registerShortcode(): void
    {
        add_shortcode('social_buttons_bar', [$this, 'renderShortcode']);
    }

    /**
     * Register the content and excerpt filters that inject the share bar.
     *
     * @return void
     */
    public function registerContentFilter(): void
    {
        // Priority 1000 so keyword/URL replacers run first. Matches v3.
        add_filter('the_content', [$this, 'filterContent'], 1000);
        // Same guard as v3: excerpt shouldn't include the buttons.
        add_filter('get_the_excerpt', [$this, 'excerptGuard'], 1);
    }

    /**
     * Enqueue the share bar stylesheet and, when needed, the copy-link script.
     *
     * @return void
     */
    public function enqueueAssets(): void
    {
        if (!$this->isEnabled()) {
            return;
        }
        $basePath = defined('PRLI_PATH') ? (string) PRLI_PATH : '';
        $baseUrl  = defined('PRLI_URL') ? (string) PRLI_URL : '';

        $cssRel = 'assets/css/social-buttons.css';
        if ($basePath !== '' && is_file($basePath . $cssRel)) {
            wp_enqueue_style(
                'prli-social-buttons',
                $baseUrl . $cssRel,
                [],
                \PrettyLinks\Bootstrap::version()
            );
        }
        // JS only needed when the Copy button is in the enabled set.
        if ($this->isCopyButtonEnabled()) {
            $jsRel = 'assets/js/social-buttons.js';
            if ($basePath !== '' && is_file($basePath . $jsRel)) {
                wp_enqueue_script(
                    'prli-social-buttons',
                    $baseUrl . $jsRel,
                    [],
                    \PrettyLinks\Bootstrap::version(),
                    true
                );
            }
        }
    }

    /**
     * Shortcode callback that renders the share bar for the current post.
     *
     * @return string
     */
    public function renderShortcode(): string
    {
        if (!$this->isEnabled()) {
            return '';
        }
        global $post;
        if (!isset($post) || !isset($post->ID)) {
            return '';
        }
        return $this->renderForPost((int) $post->ID);
    }

    /**
     * Append or prepend the share bar to post content per the configured placement.
     *
     * @param  string $content The post content being filtered.
     * @return string
     */
    public function filterContent($content): string // phpcs:ignore Squiz.Commenting.FunctionComment.ScalarTypeHintMissing -- the_content filter may pass non-string; param stays untyped and is coerced inside.
    {
        if (!is_string($content) || $content === '') {
            return (string) $content;
        }
        if (!$this->isEnabled()) {
            return $content;
        }
        // Only in-loop, singular views by default. Feeds optional.
        if (!in_the_loop() || !is_main_query()) {
            return $content;
        }
        if (is_feed() && !$this->getBool('social_buttons_show_in_feed')) {
            return $content;
        }
        if (!is_feed() && !is_singular()) {
            return $content;
        }
        // Prevent accidental recursion (a shortcode inside content re-entering this filter).
        static $running = false;
        if ($running) {
            return $content;
        }

        global $post;
        if (!isset($post) || !isset($post->ID)) {
            return $content;
        }

        // V3 parity: per-post-type toggles gate buttons independently from
        // the global `social_buttons_enabled` switch.
        if (!$this->postTypeAllowsSocial((string) ($post->post_type ?? ''))) {
            return $content;
        }

        $placement = (string) $this->getStore()->getPro('social_buttons_placement', 'bottom');
        if ($placement === 'none') {
            return $content;
        }

        $running = true;
        $bar     = $this->renderForPost((int) $post->ID);
        $running = false;

        if ($bar === '') {
            return $content;
        }
        if ($placement === 'top') {
            return $bar . $content;
        }
        if ($placement === 'top-and-bottom') {
            return $bar . $content . $bar;
        }
        // 'bottom' default
        return $content . $bar;
    }

    /**
     * Remove the content filter while an excerpt is generated so the bar is excluded.
     *
     * @param  string $excerpt The excerpt being filtered.
     * @return string
     */
    public function excerptGuard($excerpt): string // phpcs:ignore Squiz.Commenting.FunctionComment.ScalarTypeHintMissing -- get_the_excerpt filter may pass non-string; param stays untyped and is coerced inside.
    {
        if (!is_feed()) {
            remove_filter('the_content', [$this, 'filterContent'], 1000);
        }
        return (string) $excerpt;
    }

    /**
     * Render the social share bar HTML for a given post.
     *
     * @param  integer $postId The post id to render the bar for.
     * @return string
     */
    public function renderForPost(int $postId): string
    {
        if ($postId <= 0) {
            return '';
        }
        if ($this->isHiddenForPost($postId)) {
            return '';
        }

        $shareUrl = $this->resolveShareUrl($postId);
        /**
         * Filter: prli_social_bar_url
         *
         * V3 drop-in. Override the URL that appears in share links.
         *
         * @param string $shareUrl The resolved URL.
         * @param int    $postId   Source post ID.
         */
        $shareUrl = (string) apply_filters('prli_social_bar_url', $shareUrl, $postId);
        if ($shareUrl === '') {
            return '';
        }

        $title = (string) get_the_title($postId);

        $replacements = [
            'encoded_url'   => rawurlencode($shareUrl),
            'encoded_title' => rawurlencode($title),
            'share_message' => rawurlencode(trim($title . ' ' . $shareUrl)),
        ];

        $buttons = $this->resolveButtons();
        /**
         * Filter: prli_social_bar_obj
         *
         * V3 drop-in. Customize the buttons array before rendering.
         *
         * @param array  $buttons      The buttons the bar is about to render.
         * @param int    $postId       Source post ID.
         * @param string $shareUrl     Resolved share URL.
         * @param array  $replacements Token→value map used for url templating.
         */
        $buttons = (array) apply_filters('prli_social_bar_obj', $buttons, $postId, $shareUrl, $replacements);

        $items = '';
        foreach ($buttons as $btn) {
            if (!is_array($btn) || empty($btn['enabled'])) {
                continue;
            }
            $slug  = isset($btn['slug']) ? (string) $btn['slug'] : '';
            $label = isset($btn['label']) ? (string) $btn['label'] : $slug;
            $urlT  = isset($btn['url']) ? (string) $btn['url'] : '';
            if ($slug === '' || $urlT === '') {
                continue;
            }
            $href = self::applyTokens($urlT, $replacements);

            if ($slug === 'copy') {
                $items .= sprintf(
                    '<li class="prli-social-buttons__item prli-social-buttons__item--%1$s">'
                    . '<button type="button" class="prli-social-buttons__btn" data-prli-copy="%2$s" aria-label="%3$s">'
                    . '%4$s<span class="prli-social-buttons__label">%3$s</span>'
                    . '</button></li>',
                    esc_attr($slug),
                    esc_attr($shareUrl),
                    esc_attr($label),
                    self::icon($slug)
                );
                continue;
            }

            $items .= sprintf(
                '<li class="prli-social-buttons__item prli-social-buttons__item--%1$s">'
                . '<a class="prli-social-buttons__btn" href="%2$s" rel="nofollow noopener" target="_blank" aria-label="%3$s">'
                . '%4$s<span class="prli-social-buttons__label">%3$s</span>'
                . '</a></li>',
                esc_attr($slug),
                esc_url($href),
                esc_attr($label),
                self::icon($slug)
            );
        }

        if ($items === '') {
            return '';
        }

        $html = '<ul class="prli-social-buttons">' . $items . '</ul>';

        /**
         * Filter: prli_social_bar_html
         *
         * V3 drop-in. Final filter on the rendered HTML.
         *
         * @param string $html         Rendered bar.
         * @param int    $postId       Source post ID.
         * @param string $shareUrl     Resolved share URL.
         * @param array  $replacements Token→value map used for url templating.
         */
        return (string) apply_filters('prli_social_bar_html', $html, $postId, $shareUrl, $replacements);
    }

    /**
     * Replace `{{token}}` placeholders in a URL template with their values.
     *
     * @param  string                $template     The URL template containing tokens.
     * @param  array<string, string> $replacements Token to value map.
     * @return string
     */
    private static function applyTokens(string $template, array $replacements): string
    {
        $patterns = [];
        $values   = [];
        foreach ($replacements as $k => $v) {
            $patterns[] = '/\{\{' . preg_quote($k, '/') . '\}\}/';
            $values[]   = $v;
        }
        return (string) preg_replace($patterns, $values, $template);
    }

    /**
     * Merge stored per-button settings (enabled + order) with the default
     * network definitions (label/url). Users can toggle and reorder in
     * options; label/url come from code so the network definition stays
     * canonical.
     *
     * @return array<int, array<string, mixed>>
     */
    private function resolveButtons(): array
    {
        $defaults = self::defaultButtons();
        $stored   = $this->getStore()->getPro('social_buttons', []);

        // Fresh install (nothing saved yet): enable a sensible subset
        // (skip Pinterest/Reddit/Telegram/Copy) to avoid overwhelming the
        // content area.
        if (!is_array($stored) || $stored === []) {
            $initialEnabled = ['x', 'facebook', 'linkedin', 'whatsapp', 'email'];
            return array_map(static function ($b) use ($initialEnabled) {
                $b['enabled'] = in_array($b['slug'], $initialEnabled, true);
                return $b;
            }, $defaults);
        }

        // Stored data is the canonical v4 `{slug, enabled}` list — the Pro
        // migrator (normalise_social_buttons step) reshapes any legacy v3 blob
        // once on upgrade, so no runtime translation is needed here. Read the
        // enabled state by slug and join it onto the code-owned defaults.
        $enabledBySlug = [];
        foreach ($stored as $row) {
            if (is_array($row) && isset($row['slug'])) {
                $enabledBySlug[(string) $row['slug']] = !empty($row['enabled']);
            }
        }

        $out = [];
        foreach ($defaults as $def) {
            $def['enabled'] = $enabledBySlug[$def['slug']] ?? false;
            $out[]          = $def;
        }
        return $out;
    }

    /**
     * Resolve the share target URL for a post (its pretty link, or the permalink).
     *
     * @param  integer $postId The post id to resolve a share URL for.
     * @return string
     */
    private function resolveShareUrl(int $postId): string
    {
        $linkId = (int) get_post_meta($postId, '_pretty-link', true);
        if ($linkId > 0) {
            $link = $this->links->find($linkId);
            if (is_array($link) && !empty($link['pretty_url'])) {
                return (string) $link['pretty_url'];
            }
        }
        return (string) get_permalink($postId);
    }

    /**
     * Determine whether the share bar is hidden for a specific post.
     *
     * @param  integer $postId The post id to check.
     * @return boolean
     */
    private function isHiddenForPost(int $postId): bool
    {
        return PostOptions::get($postId)['hide_social_buttons'];
    }

    /**
     * Determine whether social buttons are globally enabled.
     *
     * @return boolean
     */
    private function isEnabled(): bool
    {
        return $this->getBool('social_buttons_enabled');
    }

    /**
     * Per-CPT gate. Reads `autocreate[$postType]['socbtns']` — the same unified
     * per-CPT row the AutoCreator uses. Missing row or falsy flag = no share
     * bar for that post type, even when the global master is on.
     *
     * @param  string $postType The post type slug to check.
     * @return boolean
     */
    private function postTypeAllowsSocial(string $postType): bool
    {
        $rows = $this->getStore()->getPro('autocreate', []);
        if (!is_array($rows) || !isset($rows[$postType]) || !is_array($rows[$postType])) {
            return false;
        }
        return !empty($rows[$postType]['socbtns']);
    }

    /**
     * Determine whether the copy-link button is in the enabled set.
     *
     * @return boolean
     */
    private function isCopyButtonEnabled(): bool
    {
        foreach ($this->resolveButtons() as $b) {
            if (($b['slug'] ?? '') === 'copy' && !empty($b['enabled'])) {
                return true;
            }
        }
        return false;
    }

    /**
     * Read a Pro option as a boolean.
     *
     * @param  string $key The option key to read.
     * @return boolean
     */
    private function getBool(string $key): bool
    {
        return (bool) $this->getStore()->getPro($key, false);
    }

    /**
     * Build a Pro options store instance.
     *
     * @return OptionsStore
     */
    private function getStore(): OptionsStore
    {
        return new OptionsStore();
    }

    /**
     * Inline SVG for a network slug. Simplified brand glyphs in a
     * 24-viewBox square. Returns a `<svg>` element or empty string.
     *
     * @param  string $slug The network slug to render an icon for.
     * @return string
     */
    private static function icon(string $slug): string
    {
        $paths = self::iconPaths();
        if (!isset($paths[$slug])) {
            return '';
        }
        return sprintf(
            '<svg class="prli-social-buttons__icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">%s</svg>',
            $paths[$slug]
        );
    }

    /**
     * Return the map of network slug to inline SVG path markup.
     *
     * @return array<string, string>
     */
    private static function iconPaths(): array
    {
        return [
            'x'         => '<path fill="currentColor" d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>',
            'facebook'  => '<path fill="currentColor" d="M24 12.073C24 5.446 18.627.073 12 .073S0 5.446 0 12.073c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>',
            'linkedin'  => '<path fill="currentColor" d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.063 2.063 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>',
            'pinterest' => '<path fill="currentColor" d="M12 0C5.373 0 0 5.373 0 12c0 5.084 3.163 9.426 7.627 11.174-.105-.949-.2-2.405.042-3.441.218-.937 1.407-5.965 1.407-5.965s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.284 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.402.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.357-.629-2.746-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146C9.57 23.812 10.763 24 12 24c6.624 0 12-5.373 12-12S18.624 0 12 0z"/>',
            'reddit'    => '<path fill="currentColor" d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25s.561 1.249 1.25 1.249c.688 0 1.249-.561 1.249-1.249S9.938 12 9.25 12zm5.5 0c-.687 0-1.248.562-1.248 1.25s.561 1.249 1.248 1.249c.688 0 1.249-.561 1.249-1.249S15.438 12 14.75 12zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z"/>',
            'whatsapp'  => '<path fill="currentColor" d="M.057 24l1.687-6.163a11.867 11.867 0 01-1.587-5.946C.16 5.335 5.495 0 12.05 0a11.817 11.817 0 018.413 3.488 11.824 11.824 0 013.48 8.414c-.003 6.557-5.338 11.892-11.893 11.892-1.99-.001-3.951-.5-5.688-1.448L.057 24zm6.597-3.807c1.676.995 3.276 1.591 5.392 1.592 5.448 0 9.886-4.434 9.889-9.885.002-5.462-4.415-9.89-9.881-9.892-5.452 0-9.887 4.434-9.889 9.884-.001 2.225.651 3.891 1.746 5.634l-.999 3.648 3.742-.981zm11.387-5.464c-.074-.124-.272-.198-.57-.347-.297-.149-1.758-.868-2.031-.967-.272-.099-.47-.149-.669.149-.198.297-.767.967-.94 1.165-.173.198-.347.223-.644.074-.297-.149-1.255-.462-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.297-.347.446-.521.151-.172.2-.296.3-.495.099-.198.05-.372-.025-.521-.075-.148-.669-1.611-.916-2.206-.241-.579-.486-.501-.669-.51l-.57-.01c-.198 0-.52.074-.792.372s-1.04 1.016-1.04 2.479 1.065 2.876 1.213 3.074c.149.198 2.095 3.2 5.076 4.487.709.306 1.263.489 1.694.626.712.226 1.36.194 1.872.118.571-.085 1.758-.719 2.006-1.413.248-.695.248-1.29.173-1.414z"/>',
            'telegram'  => '<path fill="currentColor" d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z"/>',
            'email'     => '<path fill="currentColor" d="M1.5 8.67v8.58a3 3 0 0 0 3 3h15a3 3 0 0 0 3-3V8.67l-8.928 5.493a3 3 0 0 1-3.144 0L1.5 8.67Z"/><path fill="currentColor" d="M22.5 6.908V6.75a3 3 0 0 0-3-3h-15a3 3 0 0 0-3 3v.158l9.714 5.978a1.5 1.5 0 0 0 1.572 0L22.5 6.908Z"/>',
            'copy'      => '<path fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M16 1H4a2 2 0 0 0-2 2v14"/><path fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M20 5H9a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2z"/>',
        ];
    }
}
