<?php

declare(strict_types=1);

namespace PrettyLinks\Pro\PrettyBar\Templates;

use PrettyLinks\Options\Store as LiteOptionsStore;
use PrettyLinks\Pro\Options\Store as OptionsStore;

/**
 * Grandfathered template for Pretty Bar links that pre-date 4.0.
 *
 * Reads the flat `prettybar_*` keys where v3 stored them: most on
 * `prli_options` (lite), plus `prettybar_hide_attrib_link` and
 * `prettybar_attrib_url` on `prlipro_options`. Preserves drop-in
 * downgrade — v3 code reads the same rows without translation.
 *
 * Colors come across bare from v3 (e.g. `000000`); normalized to
 * `#`-prefixed here for CSS output. v3 storage isn't rewritten.
 */
final class LegacyTemplate extends AbstractTemplate
{
    public const ID = 'legacy';

    /**
     * Returns the template's unique identifier.
     *
     * @return string
     */
    public function id(): string
    {
        return self::ID;
    }

    /**
     * Returns the template's human-readable label.
     *
     * @return string
     */
    public function label(): string
    {
        return __('Classic (legacy)', 'pretty-link-pro');
    }

    /**
     * Returns the resolved Classic settings read from the v3 storage layout.
     *
     * @return array<string, mixed>
     */
    public function settings(): array
    {
        // V3 stored every Classic setting on `prli_options` EXCEPT the two
        // attribution keys which it placed on `prlipro_options`. Match
        // that layout exactly so a site upgraded from v3 sees its custom
        // colors / logo / limits come through unchanged.
        $lite = new LiteOptionsStore();
        $pro  = new OptionsStore();
        return [
            'title_limit'      => (int) $lite->get('prettybar_title_limit', 25),
            'desc_limit'       => (int) $lite->get('prettybar_desc_limit', 30),
            'link_limit'       => (int) $lite->get('prettybar_link_limit', 30),
            'show_title'       => (bool) $lite->get('prettybar_show_title', '1'),
            'show_description' => (bool) $lite->get('prettybar_show_description', '1'),
            'show_share'       => (bool) $lite->get('prettybar_show_share_links', '1'),
            'show_target_url'  => (bool) $lite->get('prettybar_show_target_url_link', '1'),
            'logo_url'         => (string) $lite->get('prettybar_image_url', ''),
            'background_image' => (string) $lite->get('prettybar_background_image_url', ''),
            'bg_color'         => self::ensureHex((string) $lite->get('prettybar_color', '')),
            'text_color'       => self::ensureHex((string) $lite->get('prettybar_text_color', '000000')),
            'link_color'       => self::ensureHex((string) $lite->get('prettybar_link_color', '0000ee')),
            'hover_color'      => self::ensureHex((string) $lite->get('prettybar_hover_color', 'ababab')),
            'visited_color'    => self::ensureHex((string) $lite->get('prettybar_visited_color', '551a8b')),
            'hide_attribution' => (bool) $pro->getPro('prettybar_hide_attrib_link', false),
            'attribution_url'  => (string) $pro->getPro('prettybar_attrib_url', ''),
        ];
    }

    /**
     * Normalizes a stored color to a `#`-prefixed hex, or empty string.
     *
     * @param string $value The stored color value.
     *
     * @return string The normalized hex color.
     */
    private static function ensureHex(string $value): string
    {
        $value = trim($value);
        if ($value === '' || $value === '#') {
            return '';
        }
        return strpos($value, '#') === 0 ? $value : '#' . $value;
    }

    /**
     * Renders the Classic Pretty Bar document.
     *
     * @param array<string, mixed> $link     Link row.
     * @param string               $target   Resolved outbound URL.
     * @param array<string, mixed> $settings Resolved template settings.
     *
     * @return void
     */
    public function render(array $link, string $target, array $settings): void
    {
        $title           = (string) ($link['name'] ?? 'Pretty Link');
        $blogUrl         = home_url('/');
        $blogTitle       = get_bloginfo('name');
        $blogDescription = get_bloginfo('description');

        $shortenedTitle  = $this->truncate($title, (int) $settings['title_limit']);
        $shortenedDesc   = $this->truncate(
            (string) ($link['description'] ?? $blogDescription),
            (int) $settings['desc_limit']
        );
        $shortenedTarget = $this->truncate($target, (int) $settings['link_limit']);
        $inlineCss       = $this->inlineCss($settings);

        $this->emitHead($link, $title, $inlineCss);

        echo '<body class="prli-bar-body">';
        do_action('prli-pretty-bar-header', $link);

        // V3 stacked the bar (65px fixed) above the destination in an
        // iframe. v3 itself used a <frameset>, which modern browsers no
        // longer render — a fixed bar + full-viewport iframe delivers the
        // same visual without the deprecated element.
        echo '<div id="prettybar">';
        echo '<table width="100%" height="65px"><tr>';

        // Column 1: blog icon.
        $barImage = (string) ($settings['logo_url'] ?: '');
        echo '<td class="blog-image" valign="top"><div class="pb-cell">';
        if ($barImage !== '') {
            echo '<a href="' . esc_url($blogUrl) . '" target="_top">'
                . '<img src="' . esc_url($barImage) . '" width="48" height="48" alt=""></a>';
        } else {
            echo '&nbsp;';
        }
        echo '</div></td>';

        // Column 2: title + description.
        echo '<td class="blog-title" valign="top"><div class="pb-cell">';
        echo '<h2>';
        if ($settings['show_title']) {
            echo '<a href="' . esc_url($blogUrl) . '" title="' . esc_attr($shortenedTitle)
                . '" target="_top">' . esc_html($shortenedTitle) . '</a>';
        } else {
            echo '&nbsp;';
        }
        echo '</h2>';
        echo '<p>';
        if ($settings['show_description']) {
            echo '<span title="' . esc_attr($blogDescription) . '">'
                . esc_html($shortenedDesc) . '</span>';
        } else {
            echo '&nbsp;';
        }
        echo '</p></div></td>';

        // Column 3: target URL + share link ("retweet" cell).
        echo '<td class="retweet" valign="top"><div class="pb-cell">';
        echo '<h4>';
        if ($settings['show_target_url']) {
            echo '<a href="' . esc_url($target) . '" title="' . esc_attr(sprintf(
                // phpcs:ignore Squiz.Commenting.InlineComment.NotCapital -- WordPress translator comment, kept verbatim.
                // translators: %s: target URL.
                __('You\'re viewing: %s', 'pretty-link-pro'),
                $target
            )) . '" target="_top">' . sprintf(
                // phpcs:ignore Squiz.Commenting.InlineComment.NotCapital -- WordPress translator comment, kept verbatim.
                // translators: %s: shortened URL.
                esc_html__('Viewing: %s', 'pretty-link-pro'),
                esc_html($shortenedTarget)
            ) . '</a>';
        } else {
            echo '&nbsp;';
        }
        echo '</h4>';
        echo '<h4>';
        if ($settings['show_share']) {
            $shareUrl = 'https://x.com/intent/tweet?url=' . rawurlencode($target)
                . '&text=' . rawurlencode($title);
            echo '<a href="' . esc_url($shareUrl) . '" target="_blank" rel="noopener nofollow">'
                . esc_html__('Share on X', 'pretty-link-pro') . '</a>';
        } else {
            echo '&nbsp;';
        }
        echo '</h4></div></td>';

        // Column 4: close button + attribution.
        echo '<td valign="top"><div class="pb-cell right_container">';
        echo '<table width="100%" cellpadding="0" cellspacing="0">';
        echo '<tr><td>';
        echo '<p class="closebutton"><a href="' . esc_url($target) . '" target="_top" aria-label="'
            . esc_attr__('Close bar', 'pretty-link-pro') . '">'
            . '<svg width="18" height="18" viewBox="0 0 18 18" fill="none" aria-hidden="true">'
            . '<circle cx="9" cy="9" r="8" stroke="currentColor" stroke-width="1.5"/>'
            . '<path d="M6 6l6 6M12 6l-6 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>'
            . '</svg></a></p>';
        echo '</td></tr>';
        echo '<tr><td>';
        $attribUrl  = $this->attributionUrl((string) $settings['attribution_url']);
        $attribHtml = '<p class="powered-by small-text">'
            . esc_html__('Powered by', 'pretty-link-pro')
            . ' <a href="' . esc_url($attribUrl) . '" target="_blank" rel="noopener">'
            . esc_html__('Pretty Links', 'pretty-link-pro') . '</a></p>';
        $attribHtml = $this->attributionHtml($attribHtml, (bool) $settings['hide_attribution'], $link);
        if ($attribHtml !== '') {
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- attributionHtml() returns pre-escaped markup filtered through prli-display-attrib-link.
            echo $attribHtml;
        }
        echo '</td></tr></table>';
        echo '</div></td>';

        echo '</tr></table>';
        echo '</div>';

        // Destination: full-viewport iframe beneath the fixed bar.
        echo '<iframe class="prli-bar-frame" src="' . esc_url($target) . '" title="'
            . esc_attr($title) . '"></iframe>';

        do_action('prli-pretty-bar-footer', $link);
        echo '</body></html>';
    }

    /**
     * Builds the scoped inline CSS for the Classic bar.
     *
     * @param array<string, mixed> $settings Resolved template settings.
     *
     * @return string The inline CSS.
     */
    private function inlineCss(array $settings): string
    {
        $bg      = $this->sanitizeHex((string) $settings['bg_color'], '#ffffff');
        $text    = $this->sanitizeHex((string) $settings['text_color'], '#000000');
        $link    = $this->sanitizeHex((string) $settings['link_color'], '#0000ee');
        $hover   = $this->sanitizeHex((string) $settings['hover_color'], '#ababab');
        $visited = $this->sanitizeHex((string) $settings['visited_color'], '#551a8b');
        $bgImage = (string) $settings['background_image'];

        // Scoped to #prettybar so the classic bar colors don't leak into
        // the iframe (which loads its own document) nor into the admin
        // preview when this stylesheet isn't in use.
        $css  = '#prettybar{background-color:' . $bg . ';color:' . $text . ';}';
        $css .= '#prettybar a{color:' . $link . ';}';
        $css .= '#prettybar a:hover{color:' . $hover . ';}';
        $css .= '#prettybar a:visited{color:' . $visited . ';}';
        if ($bgImage !== '') {
            $css .= '#prettybar{background-image:url(\'' . esc_url($bgImage)
                . '\');background-repeat:no-repeat;background-position:right center;}';
        }
        return $css;
    }
}
