<?php

declare(strict_types=1);

namespace PrettyLinks\Pro\PrettyBar\Templates;

use PrettyLinks\Pro\PrettyBar\Settings;

/**
 * Modern "Floating pill" — the iframe takes the whole viewport; a compact
 * pill hovers over it at one of six anchor points (top-left, top-center,
 * top-right, bottom-left, bottom-center, bottom-right). Best for sites
 * that want minimal branding interference.
 */
final class FloatingTemplate extends AbstractTemplate
{
    public const ID = 'floating';

    private const VALID_POSITIONS = [
        'top-left',
        'top-center',
        'top-right',
        'bottom-left',
        'bottom-center',
        'bottom-right',
    ];

    /**
     * Returns the default settings for the Floating pill template.
     *
     * @return array<string, mixed>
     */
    public static function defaults(): array
    {
        return array_merge(self::sharedDefaults(), [
            // Vibrant pink→violet gradient with amber share CTA — the
            // pill is already a visual element, so defaults lean into
            // that and make it feel intentional out of the box.
            'bgType'       => 'gradient',
            'bgColor'      => '#ec4899',
            'bgColor2'     => '#8b5cf6',
            'bgAngle'      => 135,
            'textColor'    => '#ffffff',
            'accentColor'  => '#fde68a',
            'ctaTextColor' => '#111827',
            'position'     => 'bottom-right',
            // Pills don't have room for a description block.
            'showDesc'     => false,
            'showShare'    => true,
            // Dismiss + pill shape + stronger shadow are pill-typical defaults.
            // 60px is full-pill for any reasonable pill height; higher
            // values are visually identical, so the editor caps at 60.
            'showDismiss'  => true,
            'borderRadius' => 60,
            'shadow'       => 'strong',
            'logoHeight'   => 24,
            // Trimmed content caps so the pill doesn't become a mini bar.
            'titleLimit'   => 60,
            'urlLimit'     => 48,
        ]);
    }

    /**
     * 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 __('Floating pill', 'pretty-link-pro');
    }

    /**
     * Returns the resolved settings for this template.
     *
     * @return array<string, mixed>
     */
    public function settings(): array
    {
        return Settings::forTemplate(self::ID, self::defaults());
    }

    /**
     * Renders the Floating pill 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
    {
        $shared = Settings::shared();
        $title  = (string) ($link['name'] ?? 'Pretty Link');

        $this->emitHead($link, $title, $this->rootCss($settings));

        $pos = (string) ($settings['position'] ?? 'bottom-right');
        if (!in_array($pos, self::VALID_POSITIONS, true)) {
            $pos = 'bottom-right';
        }

        echo '<body class="prli-pb prli-pb-float" data-pos="' . esc_attr($pos) . '">';
        do_action('prli-pretty-bar-header', $link);
        echo '<iframe class="prli-pb-frame" src="' . esc_url($target) . '" title="' . esc_attr($title) . '"></iframe>';

        echo '<aside class="prli-pb-pill" role="complementary">';

        $logo = $this->logoImg($shared, $title);
        if ($logo !== '') {
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- logoImg() returns a pre-escaped <img> tag.
            echo '<div class="prli-pb-logo">' . $logo . '</div>';
        }

        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- metaBlock() and actionsBlock() return pre-escaped HTML.
        echo $this->metaBlock($link, $target, $settings, true) . $this->actionsBlock($link, $target, $settings, $shared);

        echo '</aside>';
        if (!empty($settings['showDismiss'])) {
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- dismissScript() returns a static inline <script> literal.
            echo $this->dismissScript();
        }
        do_action('prli-pretty-bar-footer', $link);
        echo '</body></html>';
    }
}
