<?php

namespace PhotoSphereViewer\Includes;

use Elementor\Controls_Manager;
use Elementor\Widget_Base;
use Elementor\Group_Control_Typography;
use Elementor\Repeater;
use Elementor\Modules\Promotions\Controls\Promotion_Control;

class Virtual_Tour_Viewer extends Widget_Base {

    private function is_pro_activated(): bool {
        return ProStatus::is_active();
    }

    public function get_name() {
        return 'psv-virtual-tour';
    }

    public function get_title() {
        return __('360° Virtual Tour', 'photo-sphere-viewer');
    }

    public function get_icon() {
        return 'psv-widget-icon psv-widget-icon-virtual-tour';
    }

    public function get_categories() {
        return ['photo-sphere-viewer'];
    }

    public function get_keywords() {
        return [
            'virtual tour',
            'virtual',
            'tour',
            'psv',
            'photo sphere viewer',
            '360',
            '360 tour',
            'panorama tour',
            'real estate tour',
            'walkthrough',
            'multi-scene',
            'scene',
            'hotspot',
            'compass',
            'gallery',
            'museum',
            'hotel',
        ];
    }

    public function get_script_depends() {
        return ['psv-main'];
    }

    public function get_style_depends() {
        return ['psv-style'];
    }

    protected function register_controls() {

        /**
         * Content Section
         */
        $this->start_controls_section(
            '_content_section',
            [
                'label' => __('Layout', 'photo-sphere-viewer'),
                'tab'   => Controls_Manager::TAB_CONTENT,
            ]
        );

        $this->add_control(
            'viewer_width',
            [
                'label'      => __('Width', 'photo-sphere-viewer'),
                'type'       => Controls_Manager::SLIDER,
                'size_units' => ['px', '%', 'vw'],
                'range'      => [
                    'px' => ['min' => 300, 'max' => 3000, 'step' => 5],
                    '%'  => ['min' => 0, 'max' => 100],
                ],
                'default'    => ['unit' => '%', 'size' => 100],
                'selectors'  => [
                    '{{WRAPPER}} .photo-sphere-viewer' => 'width: {{SIZE}}{{UNIT}};',
                ],
            ]
        );

        $this->add_control(
            'viewer_height',
            [
                'label'       => __('Height', 'photo-sphere-viewer'),
                'type'        => Controls_Manager::SLIDER,
                'size_units'  => ['px', '%', 'vh'],
                'default'     => ['unit' => 'vh', 'size' => 70],
                'selectors'   => [
                    '{{WRAPPER}} .photo-sphere-viewer' => 'height: {{SIZE}}{{UNIT}};',
                ],
                'render_type' => 'template',
            ]
        );

        $this->end_controls_section();

        /**
         * Scenes Section
         */
        $this->start_controls_section(
            '_scenes_section',
            [
                'label' => __('Scenes', 'photo-sphere-viewer'),
                'tab'   => Controls_Manager::TAB_CONTENT,
            ]
        );

        $scene_repeater = new Repeater();

        $scene_repeater->add_control(
            'scene_name',
            [
                'label'       => __('Scene Name', 'photo-sphere-viewer'),
                'type'        => Controls_Manager::TEXT,
                'default'     => __('Scene', 'photo-sphere-viewer'),
                'label_block' => true,
            ]
        );

        $scene_repeater->add_control(
            'scene_image',
            [
                'label'   => __('Panorama Image', 'photo-sphere-viewer'),
                'type'    => Controls_Manager::MEDIA,
                'default' => ['url' => ''],
            ]
        );

        $scene_repeater->add_control(
            'scene_thumbnail',
            [
                'label'       => __('Thumbnail', 'photo-sphere-viewer'),
                'type'        => Controls_Manager::MEDIA,
                'description' => __('Optional. Used in the gallery bar if enabled.', 'photo-sphere-viewer'),
                'default'     => ['url' => ''],
            ]
        );

        $scene_repeater->add_control(
            'scene_caption',
            [
                'label'   => __('Caption', 'photo-sphere-viewer'),
                'type'    => Controls_Manager::TEXT,
                'default' => '',
            ]
        );

        $scene_repeater->add_control(
            'scene_default_yaw',
            [
                'label'   => __('Starting Yaw (°)', 'photo-sphere-viewer'),
                'type'    => Controls_Manager::NUMBER,
                'min'     => -180,
                'max'     => 180,
                'default' => 0,
            ]
        );

        $scene_repeater->add_control(
            'scene_default_pitch',
            [
                'label'   => __('Starting Pitch (°)', 'photo-sphere-viewer'),
                'type'    => Controls_Manager::NUMBER,
                'min'     => -90,
                'max'     => 90,
                'default' => 0,
            ]
        );

        $scene_repeater->add_control(
            'scene_linked_scenes',
            [
                'label'       => __('Linked Scenes', 'photo-sphere-viewer'),
                'type'        => Controls_Manager::TEXT,
                'description' => __('Comma-separated scene numbers to link to, e.g. "2,3". Scene numbers start from 1.', 'photo-sphere-viewer'),
                'default'     => '',
                'label_block' => true,
            ]
        );

        $scene_repeater->add_control(
            'scene_link_yaws',
            [
                'label'       => __('Link Yaw Positions (°)', 'photo-sphere-viewer'),
                'type'        => Controls_Manager::TEXT,
                'description' => __('Comma-separated yaw angles for each link arrow. If empty, auto-distributed evenly.', 'photo-sphere-viewer'),
                'default'     => '',
                'label_block' => true,
            ]
        );

        $this->add_control(
            'tour_scenes',
            [
                'label'       => __('Tour Scenes', 'photo-sphere-viewer'),
                'type'        => Controls_Manager::REPEATER,
                'fields'      => $scene_repeater->get_controls(),
                'default'     => [
                    [
                        'scene_name'          => __('Key Biscayne 1', 'photo-sphere-viewer'),
                        'scene_image'         => ['url' => PSV_ASSETS_URL . 'img/key-biscayne-1.jpg'],
                        'scene_thumbnail'     => ['url' => PSV_ASSETS_URL . 'img/key-biscayne-1-thumb.jpg'],
                        'scene_caption'       => __('Key Biscayne — Scene 1', 'photo-sphere-viewer'),
                        'scene_default_yaw'   => 0,
                        'scene_default_pitch' => 0,
                        'scene_linked_scenes' => '2,3',
                        'scene_link_yaws'     => '80,270',
                    ],
                    [
                        'scene_name'          => __('Key Biscayne 2', 'photo-sphere-viewer'),
                        'scene_image'         => ['url' => PSV_ASSETS_URL . 'img/key-biscayne-2.jpg'],
                        'scene_thumbnail'     => ['url' => PSV_ASSETS_URL . 'img/key-biscayne-2-thumb.jpg'],
                        'scene_caption'       => __('Key Biscayne — Scene 2', 'photo-sphere-viewer'),
                        'scene_default_yaw'   => 0,
                        'scene_default_pitch' => 0,
                        'scene_linked_scenes' => '1,3',
                        'scene_link_yaws'     => '260,100',
                    ],
                    [
                        'scene_name'          => __('Key Biscayne 3', 'photo-sphere-viewer'),
                        'scene_image'         => ['url' => PSV_ASSETS_URL . 'img/key-biscayne-3.jpg'],
                        'scene_thumbnail'     => ['url' => PSV_ASSETS_URL . 'img/key-biscayne-3-thumb.jpg'],
                        'scene_caption'       => __('Key Biscayne — Scene 3', 'photo-sphere-viewer'),
                        'scene_default_yaw'   => 0,
                        'scene_default_pitch' => 0,
                        'scene_linked_scenes' => '1,2',
                        'scene_link_yaws'     => '200,340',
                    ],
                ],
                'title_field' => '{{{ scene_name }}}',
            ]
        );

        $this->end_controls_section();

        /**
         * Tour Settings Section
         */
        $this->start_controls_section(
            '_tour_settings_section',
            [
                'label' => __('Tour Settings', 'photo-sphere-viewer'),
                'tab'   => Controls_Manager::TAB_CONTENT,
            ]
        );

        $this->add_control(
            'start_scene',
            [
                'label'       => __('Start Scene Number', 'photo-sphere-viewer'),
                'type'        => Controls_Manager::NUMBER,
                'default'     => 1,
                'min'         => 1,
                'description' => __('Which scene to show first (1-indexed).', 'photo-sphere-viewer'),
            ]
        );

        $this->add_control(
            'use_original_image',
            [
                'label'        => __('Use Original Image (Full Resolution)', 'photo-sphere-viewer'),
                'type'         => $this->is_pro_activated() ? Controls_Manager::SWITCHER : Promotion_Control::TYPE,
                'label_on'     => __('Yes', 'photo-sphere-viewer'),
                'label_off'    => __('No', 'photo-sphere-viewer'),
                'return_value' => 'yes',
                'default'      => $this->is_pro_activated() ? 'yes' : '',
                'description'  => !$this->is_pro_activated()
                    ? __('Available in Pro version — loads each scene\'s un-scaled original upload for true 360° detail.', 'photo-sphere-viewer')
                    : __('Recommended for high-resolution panoramas (e.g. DJI Matrice). Loads each scene\'s original uploaded file instead of WordPress\'s auto-scaled copy.', 'photo-sphere-viewer'),
                'separator'    => 'before',
            ]
        );

        // $this->add_control(
        //     'render_mode',
        //     [
        //         'label'   => __('Link Render Mode', 'photo-sphere-viewer'),
        //         'type'    => $this->is_pro_activated() ? Controls_Manager::SELECT : Promotion_Control::TYPE,
        //         'default' => '3d',
        //         'options' => [
        //             '3d'      => __('3D Arrows', 'photo-sphere-viewer'),
        //             'markers' => __('Markers', 'photo-sphere-viewer'),
        //         ],
        //         'description' => !$this->is_pro_activated() ? __('Available in Pro version — defaults to 3D', 'photo-sphere-viewer') : __('How navigation links appear in the panorama.', 'photo-sphere-viewer'),
        //     ]
        // );

        $this->add_control(
            'enable_tour_gallery',
            [
                'label'        => __('Show Scene Gallery', 'photo-sphere-viewer'),
                'type'         => $this->is_pro_activated() ? Controls_Manager::SWITCHER : Promotion_Control::TYPE,
                'label_on'     => __('Yes', 'photo-sphere-viewer'),
                'label_off'    => __('No', 'photo-sphere-viewer'),
                'return_value' => 'yes',
                'default'      => $this->is_pro_activated() ? 'yes' : '',
                'description'  => !$this->is_pro_activated() ? __('Available in Pro version', 'photo-sphere-viewer') : __('Show a thumbnail gallery bar of all scenes.', 'photo-sphere-viewer'),
            ]
        );

        $this->add_control(
            'enable_tour_compass',
            [
                'label'        => __('Show Compass', 'photo-sphere-viewer'),
                'type'         => $this->is_pro_activated() ? Controls_Manager::SWITCHER : Promotion_Control::TYPE,
                'label_on'     => __('Yes', 'photo-sphere-viewer'),
                'label_off'    => __('No', 'photo-sphere-viewer'),
                'return_value' => 'yes',
                'default'      => '',
                'description'  => !$this->is_pro_activated() ? __('Available in Pro version', 'photo-sphere-viewer') : '',
            ]
        );

        $this->add_control(
            'show_navbar',
            [
                'label'        => __('Show Navbar', 'photo-sphere-viewer'),
                'type'         => Controls_Manager::SWITCHER,
                'label_on'     => __('Yes', 'photo-sphere-viewer'),
                'label_off'    => __('No', 'photo-sphere-viewer'),
                'return_value' => 'yes',
                'default'      => 'yes',
                'separator'    => 'before',
            ]
        );

        $this->add_control(
            'show_zoom',
            [
                'label'        => __('Zoom Controls', 'photo-sphere-viewer'),
                'type'         => $this->is_pro_activated() ? Controls_Manager::SWITCHER : Promotion_Control::TYPE,
                'return_value' => 'yes',
                'default'      => $this->is_pro_activated() ? 'yes' : '',
                'condition'    => ['show_navbar' => 'yes'],
                'description'  => !$this->is_pro_activated() ? __('Available in Pro version', 'photo-sphere-viewer') : '',
            ]
        );

        $this->add_control(
            'show_caption',
            [
                'label'        => __('Caption', 'photo-sphere-viewer'),
                'type'         => Controls_Manager::SWITCHER,
                'return_value' => 'yes',
                'default'      => 'yes',
                'condition'    => ['show_navbar' => 'yes'],
            ]
        );

        $this->add_control(
            'show_fullscreen',
            [
                'label'        => __('Fullscreen', 'photo-sphere-viewer'),
                'type'         => $this->is_pro_activated() ? Controls_Manager::SWITCHER : Promotion_Control::TYPE,
                'return_value' => 'yes',
                'default'      => $this->is_pro_activated() ? 'yes' : '',
                'condition'    => ['show_navbar' => 'yes'],
                'description'  => !$this->is_pro_activated() ? __('Available in Pro version', 'photo-sphere-viewer') : '',
            ]
        );

        $this->add_control(
            'show_autorotate',
            [
                'label'        => __('Autorotate', 'photo-sphere-viewer'),
                'type'         => $this->is_pro_activated() ? Controls_Manager::SWITCHER : Promotion_Control::TYPE,
                'return_value' => 'yes',
                'default'      => '',
                'condition'    => ['show_navbar' => 'yes'],
                'description'  => !$this->is_pro_activated() ? __('Available in Pro version', 'photo-sphere-viewer') : '',
            ]
        );

        $this->add_control(
            'autorotate_autoplay',
            [
                'label'        => __('Autorotate Autoplay', 'photo-sphere-viewer'),
                'type'         => Controls_Manager::SWITCHER,
                'return_value' => 'yes',
                'default'      => '',
                'condition'    => [
                    'show_navbar'     => 'yes',
                    'show_autorotate' => 'yes',
                ],
                'description'  => __('When enabled, the panorama starts rotating automatically. When disabled, the autorotate button is shown but rotation must be started manually.', 'photo-sphere-viewer'),
            ]
        );

        $this->add_control(
            'show_download',
            [
                'label'        => __('Download', 'photo-sphere-viewer'),
                'type'         => $this->is_pro_activated() ? Controls_Manager::SWITCHER : Promotion_Control::TYPE,
                'return_value' => 'yes',
                'default'      => '',
                'condition'    => ['show_navbar' => 'yes'],
                'description'  => !$this->is_pro_activated() ? __('Available in Pro version', 'photo-sphere-viewer') : '',
            ]
        );

        $this->end_controls_section();

        /**
         * Style Section
         */
        $this->start_controls_section(
            '_style_section',
            [
                'label' => __('Navbar', 'photo-sphere-viewer'),
                'tab'   => Controls_Manager::TAB_STYLE,
            ]
        );

        $this->add_control(
            'navbar_background',
            [
                'label'     => __('Background', 'photo-sphere-viewer'),
                'type'      => Controls_Manager::COLOR,
                'selectors' => [
                    '{{WRAPPER}} .psv-navbar' => 'background: {{VALUE}}',
                ],
            ]
        );

        $this->add_control(
            'title_color',
            [
                'label'     => __('Caption Color', 'photo-sphere-viewer'),
                'type'      => Controls_Manager::COLOR,
                'selectors' => [
                    '{{WRAPPER}} .psv-caption-content' => 'color: {{VALUE}}',
                ],
            ]
        );

        $this->add_group_control(
            Group_Control_Typography::get_type(),
            [
                'name'     => 'title_typography',
                'label'    => __('Typography', 'photo-sphere-viewer'),
                'selector' => '{{WRAPPER}} .psv-caption-content',
            ]
        );

        $this->end_controls_section();
    }

    protected function render() {
        $settings = $this->get_settings_for_display();
        $is_pro   = $this->is_pro_activated();
        // Pro-only feature. Free users always get Elementor's URL (the scaled
        // copy when one exists). Pro: SWITCHER returns 'yes' when ON (default),
        // '' when OFF — OFF falls back to Elementor's URL.
        $use_original = $is_pro
            && isset($settings['use_original_image'])
            && $settings['use_original_image'] === 'yes';

        $scenes = $settings['tour_scenes'] ?? [];
        if (empty($scenes)) {
            echo '<div style="padding: 20px; text-align: center; color: #999;">' . esc_html__('Please add at least one scene.', 'photo-sphere-viewer') . '</div>';
            return;
        }

        // Build navbar — Pro features gated
        $navbar_enabled = [];
        if ($is_pro && isset($settings['show_zoom']) && $settings['show_zoom'] === 'yes') $navbar_enabled[] = 'zoom';
        if (isset($settings['show_caption']) && $settings['show_caption'] === 'yes') $navbar_enabled[] = 'caption';
        if ($is_pro && isset($settings['show_download']) && $settings['show_download'] === 'yes') $navbar_enabled[] = 'download';
        if ($is_pro && isset($settings['show_autorotate']) && $settings['show_autorotate'] === 'yes') $navbar_enabled[] = 'autorotate';
        if ($is_pro && isset($settings['show_fullscreen']) && $settings['show_fullscreen'] === 'yes') $navbar_enabled[] = 'fullscreen';
        if ($is_pro && isset($settings['enable_tour_gallery']) && $settings['enable_tour_gallery'] === 'yes') $navbar_enabled[] = 'gallery';

        $navbar_options = isset($settings['show_navbar']) && $settings['show_navbar'] === 'yes'
            ? implode(',', $navbar_enabled)
            : false;

        // Build nodes for VirtualTourPlugin
        $nodes = [];
        foreach ($scenes as $index => $scene) {
            if (empty($scene['scene_image']['url'])) continue;

            $scene_panorama_url = ImageResolver::resolve($scene['scene_image'], $use_original, 'tour-scene');

            $node = [
                'id'        => 'scene-' . ($index + 1),
                'panorama'  => $scene_panorama_url,
                'name'      => $scene['scene_name'],
                'thumbnail' => !empty($scene['scene_thumbnail']['url'])
                    ? $scene['scene_thumbnail']['url']
                    : $scene_panorama_url,
                'links'     => [],
            ];

            if (!empty($scene['scene_caption'])) {
                $node['caption'] = $scene['scene_caption'];
            }

            if (!empty($scene['scene_default_yaw']) || !empty($scene['scene_default_pitch'])) {
                $node['options'] = [
                    'defaultYaw'   => ($scene['scene_default_yaw'] ?? 0) . 'deg',
                    'defaultPitch' => ($scene['scene_default_pitch'] ?? 0) . 'deg',
                ];
            }

            // Parse linked scenes
            if (!empty($scene['scene_linked_scenes'])) {
                $linked = array_map('trim', explode(',', $scene['scene_linked_scenes']));
                $yaws   = !empty($scene['scene_link_yaws'])
                    ? array_map('trim', explode(',', $scene['scene_link_yaws']))
                    : [];

                foreach ($linked as $li => $target_num) {
                    $target_num = (int) $target_num;
                    if ($target_num < 1 || $target_num > count($scenes)) continue;

                    // Auto-distribute yaw if not provided
                    if (isset($yaws[$li]) && $yaws[$li] !== '') {
                        $yaw = (float) $yaws[$li];
                    } else {
                        $yaw = count($linked) > 1
                            ? -180 + ($li * (360 / count($linked)))
                            : 0;
                    }

                    $node['links'][] = [
                        'nodeId'   => 'scene-' . $target_num,
                        'position' => [
                            'yaw'   => $yaw . 'deg',
                            'pitch' => '0deg',
                        ],
                    ];
                }
            }

            $nodes[] = $node;
        }

        if (empty($nodes)) return;

        $start_scene = isset($settings['start_scene']) ? max(1, (int) $settings['start_scene']) : 1;
        $start_node_id = 'scene-' . $start_scene;

        // Gallery items for the gallery plugin (Pro only)
        $gallery_items = [];
        if ($is_pro && isset($settings['enable_tour_gallery']) && $settings['enable_tour_gallery'] === 'yes') {
            foreach ($nodes as $node) {
                $gallery_items[] = [
                    'id'        => $node['id'],
                    'name'      => $node['name'],
                    'panorama'  => $node['panorama'],
                    'thumbnail' => $node['thumbnail'],
                ];
            }
        }

        $id = wp_unique_id('psv-tour-');

        $this->add_render_attribute('viewer', 'class', 'photo-sphere-viewer viewer');

        $data = array_filter([
            'container'          => sanitize_key($id),
            'navbar'             => $navbar_options,
            'autorotateAutoplay' => ($is_pro
                && isset($settings['show_autorotate']) && $settings['show_autorotate'] === 'yes'
                && isset($settings['autorotate_autoplay']) && $settings['autorotate_autoplay'] === 'yes'),
            'canvasBackground'   => '#333',
            'virtualTourPlugin'  => [
                'nodes'       => $nodes,
                'startNodeId' => $start_node_id,
                'renderMode'  => '3d',
            ],
            'compassPlugin' => ($is_pro && isset($settings['enable_tour_compass']) && $settings['enable_tour_compass'] === 'yes') ? [
                'size' => '120px',
            ] : null,
            'galleryPlugin' => !empty($gallery_items) ? [
                'items'         => $gallery_items,
                'visibleOnLoad' => true,
                'hideOnClick'   => true,
                'thumbnailSize' => ['width' => 200, 'height' => 100],
            ] : null,
        ]);

        $this->add_render_attribute('viewer', 'data-settings', wp_json_encode($data));

        printf(
            '<div id="%1$s" %2$s></div>',
            esc_attr($id),
            $this->get_render_attribute_string('viewer')
        );
    }
}
