<?php
/**
 * Frontend rendering: shortcode, single tour view, and viewer assets.
 *
 * @package Vist360
 */

namespace Vist360\Frontend;

defined( 'ABSPATH' ) || exit;

use Vist360\Domain\TourPostType;
use Vist360\Domain\Settings;
use Vist360\Rest\AnalyticsController;

/**
 * Renders tours on the frontend.
 */
class Shortcode {

	/**
	 * Whether viewer assets have been enqueued for this request.
	 *
	 * @var bool
	 */
	private $enqueued = false;

	/**
	 * Hook registrations.
	 */
	public function register_hooks() {
		add_action( 'init', array( $this, 'register_shortcodes' ) );
		add_filter( 'the_content', array( $this, 'render_single_tour' ) );
	}

	/**
	 * Register the tour shortcode (plus legacy alias).
	 */
	public function register_shortcodes() {
		add_shortcode( 'vist360_tour', array( $this, 'shortcode' ) );
		add_shortcode( 'vist360_panorama_tour', array( $this, 'shortcode' ) );
	}

	/**
	 * Shortcode handler.
	 *
	 * @param array|string $atts Shortcode attributes.
	 * @return string
	 */
	public function shortcode( $atts ) {
		$atts = shortcode_atts(
			array(
				'id'     => 0,
				'height' => 0,
			),
			$atts,
			'vist360_tour'
		);

		return $this->render_tour( (int) $atts['id'], (int) $atts['height'] );
	}

	/**
	 * Append the viewer when viewing a single tour permalink.
	 *
	 * @param string $content Post content.
	 * @return string
	 */
	public function render_single_tour( $content ) {
		if ( is_singular( TourPostType::POST_TYPE ) && in_the_loop() && is_main_query() ) {
			return $content . $this->render_tour( get_the_ID() );
		}
		return $content;
	}

	/**
	 * Render the viewer markup for a tour.
	 *
	 * @param int $tour_id Tour post ID.
	 * @param int $height  Optional height override in pixels.
	 * @return string
	 */
	public function render_tour( $tour_id, $height = 0 ) {
		$post = get_post( $tour_id );

		if ( ! $post || TourPostType::POST_TYPE !== $post->post_type ) {
			return '';
		}

		$can_preview = current_user_can( 'edit_post', $tour_id );

		if ( 'publish' !== $post->post_status && ! $can_preview ) {
			return '';
		}

		if ( post_password_required( $post ) ) {
			return get_the_password_form( $post );
		}

		$scenes = get_post_meta( $tour_id, '_vist360_scenes', true );

		if ( empty( $scenes ) || ! is_array( $scenes ) ) {
			return $can_preview
				? '<p>' . esc_html__( 'This tour has no scenes yet. Add scenes in the tour editor.', 'vistour-virtual-tour-builder' ) . '</p>'
				: '';
		}

		$viewer = wp_parse_args(
			(array) get_post_meta( $tour_id, '_vist360_viewer', true ),
			Settings::viewer_defaults()
		);

		if ( $height > 0 ) {
			$viewer['height'] = min( 1200, max( 200, $height ) );
		}

		foreach ( $scenes as &$scene ) {
			$scene['image_url'] = $scene['image_id'] ? wp_get_attachment_image_url( $scene['image_id'], 'full' ) : '';
			$scene['thumb_url'] = $scene['image_id'] ? wp_get_attachment_image_url( $scene['image_id'], 'medium' ) : '';

			foreach ( $scene['hotspots'] as &$hotspot ) {
				if ( ! empty( $hotspot['media_id'] ) ) {
					$hotspot['media_url'] = wp_get_attachment_url( $hotspot['media_id'] );
				}
			}
			unset( $hotspot );
		}
		unset( $scene );

		$settings = Settings::get();

		$config = array(
			'tourId'    => $tour_id,
			'title'     => get_the_title( $post ),
			'scenes'    => $scenes,
			'viewer'    => $viewer,
			'shareUrl'  => get_permalink( $post ),
			'analytics' => (bool) $settings['analytics_enabled'],
			'restUrl'   => esc_url_raw( rest_url( AnalyticsController::REST_NAMESPACE . '/track' ) ),
			'i18n'      => array(
				'loading'    => __( 'Loading tour…', 'vistour-virtual-tour-builder' ),
				'fullscreen' => __( 'Toggle fullscreen', 'vistour-virtual-tour-builder' ),
				'autorotate' => __( 'Toggle auto-rotate', 'vistour-virtual-tour-builder' ),
				'share'      => __( 'Share', 'vistour-virtual-tour-builder' ),
				'scenes'     => __( 'Scenes', 'vistour-virtual-tour-builder' ),
				'close'      => __( 'Close', 'vistour-virtual-tour-builder' ),
				'copyLink'   => __( 'Copy link', 'vistour-virtual-tour-builder' ),
				'webglError' => __( 'Your browser does not support WebGL, which is required to display this tour.', 'vistour-virtual-tour-builder' ),
			),
		);

		/**
		 * Filters the viewer configuration passed to the frontend.
		 *
		 * @since 1.0.0
		 *
		 * @param array $config  Viewer configuration.
		 * @param int   $tour_id Tour post ID.
		 */
		$config = apply_filters( 'vist360_viewer_config', $config, $tour_id );

		$this->enqueue_viewer();

		return sprintf(
			'<div class="vist360-viewer" style="height:%dpx" data-vist360=\'%s\'></div>',
			(int) $viewer['height'],
			esc_attr( wp_json_encode( $config ) )
		);
	}

	/**
	 * Enqueue viewer assets on demand.
	 */
	private function enqueue_viewer() {
		if ( $this->enqueued ) {
			return;
		}
		$this->enqueued = true;

		$asset_file = VIST360_DIR . 'assets/build/frontend.asset.php';
		$asset      = file_exists( $asset_file )
			? include $asset_file
			: array(
				'dependencies' => array(),
				'version'      => VIST360_VERSION,
			);

		wp_enqueue_script(
			'vist360-frontend',
			VIST360_URL . 'assets/build/frontend.js',
			$asset['dependencies'],
			$asset['version'],
			true
		);

		wp_enqueue_style(
			'vist360-frontend',
			VIST360_URL . 'assets/build/frontend.css',
			array(),
			$asset['version']
		);
	}
}
