<?php

namespace Calio\Widgets;

use Elementor\Controls_Manager;
use Elementor\Group_Control_Typography;

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Animated text link widget with underline, reveal and hand-drawn hover styles.
 */
class AnimatedLinkWidget extends BaseWidget
{
    public function get_name(): string
    {
        return 'calio-animated-link';
    }

    public function get_title(): string
    {
        return esc_html__('Animated Link', 'calio-addon');
    }

    public function get_icon(): string
    {
        return 'eicon-editor-link';
    }

    public function get_style_depends(): array
    {
        if ($this->is_calio_edit_or_preview_mode()) {
            return ['calio-styles', 'calio-widget-animated-link'];
        }

        return ['calio-widget-animated-link'];
    }

    public function get_script_depends(): array
    {
        return [];
    }

    public function get_keywords(): array
    {
        return array_merge(parent::get_keywords(), ['animated', 'link', 'hover', 'underline', 'text']);
    }

    protected function register_controls(): void
    {
        $this->start_controls_section(
            'section_content',
            [
                'label' => esc_html__('Animated Link', 'calio-addon'),
            ]
        );

        $this->add_control(
            'link_style',
            [
                'label' => esc_html__('Style', 'calio-addon'),
                'type' => Controls_Manager::SELECT,
                'default' => 'signal-line',
                'options' => [
                    'signal-line' => esc_html__('Signal Line', 'calio-addon'),
                    'counter-current' => esc_html__('Counter Current', 'calio-addon'),
                    'soft-rise' => esc_html__('Soft Rise', 'calio-addon'),
                    'elastic-pop' => esc_html__('Elastic Pop', 'calio-addon'),
                    'split-beam' => esc_html__('Split Beam', 'calio-addon'),
                    'axis-pulse' => esc_html__('Axis Pulse', 'calio-addon'),
                    'glitch-spark' => esc_html__('Glitch Spark', 'calio-addon'),
                    'orbit-arc' => esc_html__('Orbit Arc', 'calio-addon'),
                    'twin-stream' => esc_html__('Twin Stream', 'calio-addon'),
                    'wave-runner' => esc_html__('Wave Runner', 'calio-addon'),
                    'marker-lift' => esc_html__('Marker Lift', 'calio-addon'),
                    'mirror-loop' => esc_html__('Mirror Loop', 'calio-addon'),
                    'sketch-trail' => esc_html__('Sketch Trail', 'calio-addon'),
                    'cover-flash' => esc_html__('Cover Flash', 'calio-addon'),
                    'echo-stack' => esc_html__('Echo Stack', 'calio-addon'),
                    'prism-scan' => esc_html__('Prism Scan', 'calio-addon'),
                    'corner-frame' => esc_html__('Corner Frame', 'calio-addon'),
                    'magnetic-dot' => esc_html__('Magnetic Dot', 'calio-addon'),
                    'bracket-shift' => esc_html__('Bracket Shift', 'calio-addon'),
                    'halo-sweep' => esc_html__('Halo Sweep', 'calio-addon'),
                ],
            ]
        );

        $this->add_control(
            'link_text',
            [
                'label' => esc_html__('Text', 'calio-addon'),
                'type' => Controls_Manager::TEXT,
                'default' => esc_html__('Animated Link', 'calio-addon'),
                'dynamic' => ['active' => true],
                'label_block' => true,
            ]
        );

        $this->add_control(
            'link_url',
            [
                'label' => esc_html__('Link', 'calio-addon'),
                'type' => Controls_Manager::URL,
                'default' => [
                    'url' => '',
                ],
                'dynamic' => ['active' => true],
            ]
        );

        $this->add_responsive_control(
            'alignment',
            [
                'label' => esc_html__('Alignment', 'calio-addon'),
                'type' => Controls_Manager::CHOOSE,
                'options' => [
                    'left' => [
                        'title' => esc_html__('Left', 'calio-addon'),
                        'icon' => 'eicon-text-align-left',
                    ],
                    'center' => [
                        'title' => esc_html__('Center', 'calio-addon'),
                        'icon' => 'eicon-text-align-center',
                    ],
                    'right' => [
                        'title' => esc_html__('Right', 'calio-addon'),
                        'icon' => 'eicon-text-align-right',
                    ],
                ],
                'default' => 'left',
                'selectors' => [
                    '{{WRAPPER}} .calio-animated-link-wrap' => 'text-align: {{VALUE}};',
                ],
            ]
        );

        $this->end_controls_section();

        $this->start_controls_section(
            'section_style',
            [
                'label' => esc_html__('Animated Link', 'calio-addon'),
                'tab' => Controls_Manager::TAB_STYLE,
            ]
        );

        $this->add_control(
            'link_text_color',
            [
                'label' => esc_html__('Color', 'calio-addon'),
                'type' => Controls_Manager::COLOR,
                'selectors' => [
                    '{{WRAPPER}} .calio-animated-link' => 'color: {{VALUE}};',
                ],
            ]
        );

        $this->add_control(
            'link_hover_text_color',
            [
                'label' => esc_html__('Hover Color', 'calio-addon'),
                'type' => Controls_Manager::COLOR,
                'selectors' => [
                    '{{WRAPPER}} .calio-animated-link:hover, {{WRAPPER}} .calio-animated-link:focus-visible' => 'color: {{VALUE}};',
                ],
            ]
        );

        $this->add_control(
            'link_style_color',
            [
                'label' => esc_html__('Style Color', 'calio-addon'),
                'type' => Controls_Manager::COLOR,
                'selectors' => [
                    '{{WRAPPER}} .calio-animated-link' => '--calio-animated-link-accent: {{VALUE}};',
                    '{{WRAPPER}} .calio-animated-link::before, {{WRAPPER}} .calio-animated-link::after' => 'background-color: {{VALUE}};',
                    '{{WRAPPER}} .calio-animated-link .calio-animated-link__graphic' => 'stroke: {{VALUE}};',
                ],
            ]
        );

        $this->add_responsive_control(
            'link_padding',
            [
                'label' => esc_html__('Padding', 'calio-addon'),
                'type' => Controls_Manager::DIMENSIONS,
                'size_units' => ['px', 'em', '%'],
                'selectors' => [
                    '{{WRAPPER}} .calio-animated-link' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
                ],
            ]
        );

        $this->add_responsive_control(
            'line_thickness',
            [
                'label' => esc_html__('Line Thickness', 'calio-addon'),
                'type' => Controls_Manager::SLIDER,
                'size_units' => ['px'],
                'range' => [
                    'px' => [
                        'min' => 1,
                        'max' => 12,
                    ],
                ],
                'default' => [
                    'size' => 1,
                    'unit' => 'px',
                ],
                'selectors' => [
                    '{{WRAPPER}} .calio-animated-link' => '--calio-animated-link-line: {{SIZE}}{{UNIT}};',
                ],
            ]
        );

        $this->add_responsive_control(
            'line_offset',
            [
                'label' => esc_html__('Line Offset', 'calio-addon'),
                'type' => Controls_Manager::SLIDER,
                'size_units' => ['px', 'em'],
                'range' => [
                    'px' => [
                        'min' => -12,
                        'max' => 24,
                    ],
                    'em' => [
                        'min' => -1,
                        'max' => 2,
                        'step' => 0.1,
                    ],
                ],
                'default' => [
                    'size' => 0,
                    'unit' => 'px',
                ],
                'selectors' => [
                    '{{WRAPPER}} .calio-animated-link' => '--calio-animated-link-offset: {{SIZE}}{{UNIT}};',
                ],
            ]
        );

        $this->add_control(
            'transition_speed',
            [
                'label' => esc_html__('Transition Speed', 'calio-addon'),
                'type' => Controls_Manager::SLIDER,
                'size_units' => ['ms'],
                'range' => [
                    'ms' => [
                        'min' => 100,
                        'max' => 1200,
                        'step' => 50,
                    ],
                ],
                'default' => [
                    'size' => 300,
                    'unit' => 'ms',
                ],
                'selectors' => [
                    '{{WRAPPER}} .calio-animated-link' => '--calio-animated-link-speed: {{SIZE}}{{UNIT}};',
                ],
            ]
        );

        $this->add_group_control(
            Group_Control_Typography::get_type(),
            [
                'name' => 'link_typography',
                'selector' => '{{WRAPPER}} .calio-animated-link',
            ]
        );

        $this->end_controls_section();
    }

    protected function render(): void
    {
        $settings = $this->get_settings_for_display();
        $text = isset($settings['link_text']) ? trim((string) $settings['link_text']) : '';

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

        $style = isset($settings['link_style']) ? sanitize_html_class((string) $settings['link_style']) : 'signal-line';
        $style = $this->normalize_style_slug($style);
        $supported_styles = [
            'signal-line',
            'counter-current',
            'soft-rise',
            'elastic-pop',
            'split-beam',
            'axis-pulse',
            'glitch-spark',
            'orbit-arc',
            'twin-stream',
            'wave-runner',
            'marker-lift',
            'mirror-loop',
            'sketch-trail',
            'cover-flash',
            'echo-stack',
            'prism-scan',
            'corner-frame',
            'magnetic-dot',
            'bracket-shift',
            'halo-sweep',
        ];

        if (!in_array($style, $supported_styles, true)) {
            $style = 'signal-line';
        }

        $attributes = $this->build_link_attributes($settings, $style, $text);

        echo '<div class="calio-animated-link-wrap">';
        echo '<a ' . wp_kses_data($attributes) . '>';
        echo wp_kses($this->link_inner_markup($style, $text), $this->allowed_link_inner_markup());
        echo '</a>';
        echo '</div>';
    }

    /**
     * @param array<string, mixed> $settings
     */
    private function build_link_attributes(array $settings, string $style, string $text): string
    {
        $link = isset($settings['link_url']) && is_array($settings['link_url']) ? $settings['link_url'] : [];
        $href = !empty($link['url']) ? (string) $link['url'] : '#';
        $classes = [
            'calio-animated-link',
            'calio-animated-link--' . sanitize_html_class($style),
        ];
        $attributes = [
            'class' => implode(' ', $classes),
            'href' => esc_url($href),
        ];

        if ($style === 'mirror-loop') {
            $attributes['data-text'] = $text;
        }

        $rel = [];
        if (!empty($link['is_external'])) {
            $attributes['target'] = '_blank';
            $rel[] = 'noopener';
        }

        if (!empty($link['nofollow'])) {
            $rel[] = 'nofollow';
        }

        if ($rel !== []) {
            $attributes['rel'] = implode(' ', array_unique($rel));
        }

        $pairs = [];
        foreach ($attributes as $name => $value) {
            if ($value === '') {
                continue;
            }

            $pairs[] = sanitize_key((string) $name) . '="' . esc_attr((string) $value) . '"';
        }

        return implode(' ', $pairs);
    }

    private function link_inner_markup(string $style, string $text): string
    {
        $escaped_text = esc_html($text);

        if (in_array($style, ['mirror-loop', 'split-beam', 'axis-pulse', 'elastic-pop', 'glitch-spark', 'prism-scan', 'bracket-shift'], true)) {
            return '<span>' . $escaped_text . '</span>';
        }

        if ($style === 'wave-runner') {
            return '<span>' . $escaped_text . '</span>' . $this->slide_graphic();
        }

        if ($style === 'orbit-arc') {
            return '<span>' . $escaped_text . '</span>' . $this->arc_graphic();
        }

        if ($style === 'sketch-trail') {
            return '<span>' . $escaped_text . '</span>' . $this->scribble_graphic();
        }

        return $escaped_text;
    }

    private function slide_graphic(): string
    {
        return '<svg class="calio-animated-link__graphic calio-animated-link__graphic--slide" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none" aria-hidden="true" focusable="false"><path d="M0 48 C180 58 260 36 400 48 C540 60 620 34 790 48 C940 60 1040 38 1200 48"></path></svg>';
    }

    private function arc_graphic(): string
    {
        return '<svg class="calio-animated-link__graphic calio-animated-link__graphic--arc" width="100%" height="22" viewBox="0 0 80 22" aria-hidden="true" focusable="false"><path pathLength="1" d="M3 4 C21 24 57 25 77 9"></path></svg>';
    }

    private function scribble_graphic(): string
    {
        return '<svg class="calio-animated-link__graphic calio-animated-link__graphic--scribble" width="100%" height="12" viewBox="0 0 120 12" aria-hidden="true" focusable="false"><path pathLength="1" d="M1 7 C9 2 16 10 25 5 C33 1 38 11 47 6 C59 -1 66 13 77 5 C88 -2 95 10 105 6 C111 3 116 4 119 7"></path></svg>';
    }

    private function normalize_style_slug(string $style): string
    {
        $legacy_map = [
            'metis' => 'signal-line',
            'carpo' => 'counter-current',
            'dia' => 'soft-rise',
            'eirene' => 'elastic-pop',
            'elara' => 'split-beam',
            'ersa' => 'axis-pulse',
            'helike' => 'glitch-spark',
            'herse' => 'orbit-arc',
            'io' => 'twin-stream',
            'iocaste' => 'wave-runner',
            'kale' => 'marker-lift',
            'leda' => 'mirror-loop',
            'carme' => 'sketch-trail',
            'mneme' => 'cover-flash',
            'thebe' => 'echo-stack',
        ];

        return $legacy_map[$style] ?? $style;
    }

    /**
     * @return array<string, array<string, bool>>
     */
    private function allowed_link_inner_markup(): array
    {
        return [
            'span' => [
                'class' => true,
            ],
            'svg' => [
                'aria-hidden' => true,
                'class' => true,
                'focusable' => true,
                'height' => true,
                'preserveaspectratio' => true,
                'viewbox' => true,
                'width' => true,
            ],
            'path' => [
                'd' => true,
                'pathlength' => true,
            ],
        ];
    }
}
