<?php
/**
 * Iframe embed widget.
 *
 * @package IMPACT_WIDGETS_ELEMENTOR
 */

namespace ImpactAddons\ImpactWidgetsForElementor\Widgets;

use Elementor\Controls_Manager;
use Elementor\Group_Control_Border;
use Elementor\Group_Control_Box_Shadow;
use Elementor\Widget_Base;

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

class Iframe_Embed extends Widget_Base {
	public function get_name(): string {
		return 'impact_widgets_elementor_iframe-embed';
	}

	public function get_title(): string {
		return esc_html__( 'Iframe Embed', 'impact-widgets-for-elementor' );
	}

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

	public function get_categories(): array {
		return array( 'impact-widgets-elementor' );
	}

	public function get_style_depends(): array {
		return array( 'impact_widgets_elementor_iframe-embed' );
	}

	protected function register_controls(): void {
		$this->register_content_controls();
		$this->register_style_controls();
	}

	private function register_content_controls(): void {
		$this->start_controls_section(
			'section_content',
			array(
				'label' => esc_html__( 'Embed', 'impact-widgets-for-elementor' ),
			)
		);

		$this->add_control(
			'embed_type',
			array(
				'label'   => esc_html__( 'Embed Type', 'impact-widgets-for-elementor' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'video',
				'options' => array(
					'video'   => esc_html__( 'Video Embed', 'impact-widgets-for-elementor' ),
					'map'     => esc_html__( 'Map Embed', 'impact-widgets-for-elementor' ),
					'browser' => esc_html__( 'Browser Embed', 'impact-widgets-for-elementor' ),
					'custom'  => esc_html__( 'Custom Iframe', 'impact-widgets-for-elementor' ),
				),
			)
		);

		$this->add_control(
			'embed_url',
			array(
				'label'       => esc_html__( 'Embed URL', 'impact-widgets-for-elementor' ),
				'type'        => Controls_Manager::TEXT,
				'label_block' => true,
				'default'     => 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
				'placeholder' => esc_html__( 'Paste a YouTube, Vimeo, Google Maps, or iframe URL', 'impact-widgets-for-elementor' ),
				'description' => esc_html__( 'For video/map links, the widget tries to convert common public URLs into embed-friendly URLs automatically.', 'impact-widgets-for-elementor' ),
			)
		);

		$this->add_control(
			'iframe_title',
			array(
				'label'       => esc_html__( 'Iframe Title', 'impact-widgets-for-elementor' ),
				'type'        => Controls_Manager::TEXT,
				'default'     => esc_html__( 'Embedded content', 'impact-widgets-for-elementor' ),
				'placeholder' => esc_html__( 'Enter iframe title for accessibility', 'impact-widgets-for-elementor' ),
			)
		);

		$this->add_control(
			'show_browser_chrome',
			array(
				'label'        => esc_html__( 'Show Browser Chrome', 'impact-widgets-for-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Yes', 'impact-widgets-for-elementor' ),
				'label_off'    => esc_html__( 'No', 'impact-widgets-for-elementor' ),
				'return_value' => 'yes',
				'default'      => 'yes',
				'condition'    => array(
					'embed_type' => array( 'browser', 'custom' ),
				),
			)
		);

		$this->add_control(
			'browser_label',
			array(
				'label'       => esc_html__( 'Browser Address Label', 'impact-widgets-for-elementor' ),
				'type'        => Controls_Manager::TEXT,
				'label_block' => true,
				'placeholder' => esc_html__( 'https://example.com', 'impact-widgets-for-elementor' ),
				'description' => esc_html__( 'Leave empty to show the iframe URL automatically.', 'impact-widgets-for-elementor' ),
				'condition'   => array(
					'show_browser_chrome' => 'yes',
					'embed_type'          => array( 'browser', 'custom' ),
				),
			)
		);

		$this->add_control(
			'size_mode',
			array(
				'label'   => esc_html__( 'Sizing Mode', 'impact-widgets-for-elementor' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'aspect-ratio',
				'options' => array(
					'aspect-ratio' => esc_html__( 'Aspect Ratio', 'impact-widgets-for-elementor' ),
					'fixed-height' => esc_html__( 'Fixed Height', 'impact-widgets-for-elementor' ),
				),
			)
		);

		$this->add_control(
			'aspect_ratio',
			array(
				'label'     => esc_html__( 'Aspect Ratio', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => '16 / 9',
				'options'   => array(
					'21 / 9' => esc_html__( '21:9', 'impact-widgets-for-elementor' ),
					'16 / 9' => esc_html__( '16:9', 'impact-widgets-for-elementor' ),
					'4 / 3'  => esc_html__( '4:3', 'impact-widgets-for-elementor' ),
					'1 / 1'  => esc_html__( '1:1', 'impact-widgets-for-elementor' ),
					'9 / 16' => esc_html__( '9:16', 'impact-widgets-for-elementor' ),
				),
				'condition' => array(
					'size_mode' => 'aspect-ratio',
				),
				'selectors' => array(
					'{{WRAPPER}} .iaew-iframe-embed' => '--iaew-iframe-aspect-ratio: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'fixed_height',
			array(
				'label'      => esc_html__( 'Iframe Height', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'vh' ),
				'range'      => array(
					'px' => array(
						'min' => 160,
						'max' => 1200,
					),
					'vh' => array(
						'min' => 20,
						'max' => 100,
					),
				),
				'default'    => array(
					'size' => 520,
					'unit' => 'px',
				),
				'condition'  => array(
					'size_mode' => 'fixed-height',
				),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-iframe-embed' => '--iaew-iframe-height: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'embed_width',
			array(
				'label'      => esc_html__( 'Max Width', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( '%', 'px' ),
				'range'      => array(
					'%' => array(
						'min' => 20,
						'max' => 100,
					),
					'px' => array(
						'min' => 240,
						'max' => 1600,
					),
				),
				'default'    => array(
					'size' => 100,
					'unit' => '%',
				),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-iframe-embed' => 'max-width: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'embed_alignment',
			array(
				'label'     => esc_html__( 'Alignment', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::CHOOSE,
				'options'   => array(
					'flex-start' => array(
						'title' => esc_html__( 'Left', 'impact-widgets-for-elementor' ),
						'icon'  => 'eicon-text-align-left',
					),
					'center' => array(
						'title' => esc_html__( 'Center', 'impact-widgets-for-elementor' ),
						'icon'  => 'eicon-text-align-center',
					),
					'flex-end' => array(
						'title' => esc_html__( 'Right', 'impact-widgets-for-elementor' ),
						'icon'  => 'eicon-text-align-right',
					),
				),
				'default'   => 'center',
				'toggle'    => true,
				'selectors' => array(
					'{{WRAPPER}} .iaew-iframe-embed-shell' => 'justify-content: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'lazy_load',
			array(
				'label'        => esc_html__( 'Lazy Load', 'impact-widgets-for-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Yes', 'impact-widgets-for-elementor' ),
				'label_off'    => esc_html__( 'No', 'impact-widgets-for-elementor' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'allow_fullscreen',
			array(
				'label'        => esc_html__( 'Allow Fullscreen', 'impact-widgets-for-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Yes', 'impact-widgets-for-elementor' ),
				'label_off'    => esc_html__( 'No', 'impact-widgets-for-elementor' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'embed_notice',
			array(
				'type'            => Controls_Manager::RAW_HTML,
				'raw'             => esc_html__( 'Some websites block iframe embedding with browser security headers. If a page does not load inside the widget, use that site’s official embed URL instead.', 'impact-widgets-for-elementor' ),
				'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
			)
		);

		$this->end_controls_section();
	}

	private function register_style_controls(): void {
		$this->start_controls_section(
			'section_style_frame',
			array(
				'label' => esc_html__( 'Frame', 'impact-widgets-for-elementor' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_control(
			'frame_background',
			array(
				'label'     => esc_html__( 'Background Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-iframe-embed' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'frame_border_radius',
			array(
				'label'      => esc_html__( 'Border Radius', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', '%' ),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-iframe-embed' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Border::get_type(),
			array(
				'name'     => 'frame_border',
				'selector' => '{{WRAPPER}} .iaew-iframe-embed',
			)
		);

		$this->add_group_control(
			Group_Control_Box_Shadow::get_type(),
			array(
				'name'     => 'frame_shadow',
				'selector' => '{{WRAPPER}} .iaew-iframe-embed',
			)
		);

		$this->end_controls_section();

		$this->start_controls_section(
			'section_style_browser',
			array(
				'label'     => esc_html__( 'Browser Chrome', 'impact-widgets-for-elementor' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array(
					'show_browser_chrome' => 'yes',
				),
			)
		);

		$this->add_control(
			'browser_bar_background',
			array(
				'label'     => esc_html__( 'Top Bar Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-iframe-embed__browser-bar' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'browser_address_background',
			array(
				'label'     => esc_html__( 'Address Bar Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-iframe-embed__browser-address' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'browser_address_color',
			array(
				'label'     => esc_html__( 'Address Text Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-iframe-embed__browser-address' => 'color: {{VALUE}};',
				),
			)
		);

		$this->end_controls_section();
	}

	protected function render(): void {
		$settings             = $this->get_settings_for_display();
		$embed_type           = isset( $settings['embed_type'] ) ? sanitize_key( $settings['embed_type'] ) : 'video';
		if ( ! in_array( $embed_type, array( 'video', 'map', 'browser', 'custom' ), true ) ) {
			$embed_type = 'video';
		}
		$iframe_url           = $this->normalize_embed_url( (string) ( $settings['embed_url'] ?? '' ), $embed_type );
		$iframe_title         = sanitize_text_field( $settings['iframe_title'] ?? '' );
		$size_mode            = isset( $settings['size_mode'] ) ? sanitize_key( $settings['size_mode'] ) : 'aspect-ratio';
		$show_browser_chrome  = isset( $settings['show_browser_chrome'] ) && 'yes' === $settings['show_browser_chrome'];
		$allow_fullscreen     = isset( $settings['allow_fullscreen'] ) && 'yes' === $settings['allow_fullscreen'];
		$loading_mode         = isset( $settings['lazy_load'] ) && 'yes' === $settings['lazy_load'] ? 'lazy' : 'eager';
		$browser_label        = sanitize_text_field( $settings['browser_label'] ?? '' );

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

		if ( '' === $iframe_title ) {
			$iframe_title = esc_html__( 'Embedded content', 'impact-widgets-for-elementor' );
		}

		if ( '' === $browser_label ) {
			$browser_label = preg_replace( '#^https?://#', '', $iframe_url );
		}

		$classes = array(
			'iaew-iframe-embed',
			'iaew-iframe-embed--' . sanitize_html_class( $embed_type ),
			'iaew-iframe-embed--' . sanitize_html_class( $size_mode ),
		);

		if ( $show_browser_chrome ) {
			$classes[] = 'iaew-iframe-embed--has-browser';
		}

		$this->add_render_attribute( 'shell', 'class', 'iaew-iframe-embed-shell' );
		$this->add_render_attribute( 'wrapper', 'class', $classes );
		$this->add_render_attribute(
			'iframe',
			array(
				'class'           => 'iaew-iframe-embed__iframe',
				'src'             => esc_url( $iframe_url ),
				'title'           => esc_attr( $iframe_title ),
				'loading'         => esc_attr( $loading_mode ),
				'referrerpolicy'  => 'strict-origin-when-cross-origin',
				'allow'           => 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share',
			)
		);

		if ( $allow_fullscreen ) {
			$this->add_render_attribute( 'iframe', 'allowfullscreen', 'allowfullscreen' );
		}

		?>
		<div <?php $this->print_render_attribute_string( 'shell' ); ?>>
			<div <?php $this->print_render_attribute_string( 'wrapper' ); ?>>
				<?php if ( $show_browser_chrome ) : ?>
					<div class="iaew-iframe-embed__browser-bar" aria-hidden="true">
						<div class="iaew-iframe-embed__browser-actions">
							<span class="iaew-iframe-embed__dot iaew-iframe-embed__dot--close"></span>
							<span class="iaew-iframe-embed__dot iaew-iframe-embed__dot--minimize"></span>
							<span class="iaew-iframe-embed__dot iaew-iframe-embed__dot--maximize"></span>
						</div>
						<div class="iaew-iframe-embed__browser-address"><?php echo esc_html( $browser_label ); ?></div>
					</div>
				<?php endif; ?>

				<div class="iaew-iframe-embed__viewport">
					<iframe <?php $this->print_render_attribute_string( 'iframe' ); ?>></iframe>
				</div>
			</div>
		</div>
		<?php
	}

	private function normalize_embed_url( string $url, string $embed_type ): string {
		$url = trim( $url );

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

		$sanitized_url = esc_url_raw( $url );

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

		if ( 'video' === $embed_type ) {
			return $this->normalize_video_url( $sanitized_url );
		}

		if ( 'map' === $embed_type ) {
			return $this->normalize_map_url( $sanitized_url );
		}

		return $sanitized_url;
	}

	private function normalize_video_url( string $url ): string {
		$parts = wp_parse_url( $url );

		if ( ! is_array( $parts ) || empty( $parts['host'] ) ) {
			return $url;
		}

		$host = strtolower( (string) $parts['host'] );

		if ( false !== strpos( $host, 'youtu.be' ) && ! empty( $parts['path'] ) ) {
			$video_id = trim( (string) $parts['path'], '/' );

			if ( '' !== $video_id ) {
				return 'https://www.youtube.com/embed/' . rawurlencode( $video_id );
			}
		}

		if ( false !== strpos( $host, 'youtube.com' ) ) {
			if ( ! empty( $parts['path'] ) && false !== strpos( (string) $parts['path'], '/embed/' ) ) {
				return $url;
			}

			if ( ! empty( $parts['query'] ) ) {
				parse_str( (string) $parts['query'], $query_vars );

				if ( ! empty( $query_vars['v'] ) ) {
					return 'https://www.youtube.com/embed/' . rawurlencode( (string) $query_vars['v'] );
				}
			}
		}

		if ( false !== strpos( $host, 'vimeo.com' ) && ! empty( $parts['path'] ) ) {
			$video_id = trim( (string) $parts['path'], '/' );

			if ( '' !== $video_id && false === strpos( $host, 'player.vimeo.com' ) ) {
				return 'https://player.vimeo.com/video/' . rawurlencode( $video_id );
			}
		}

		return $url;
	}

	private function normalize_map_url( string $url ): string {
		$parts = wp_parse_url( $url );

		if ( ! is_array( $parts ) ) {
			return $url;
		}

		if ( ! empty( $parts['host'] ) && false !== strpos( strtolower( (string) $parts['host'] ), 'google.' ) ) {
			if ( ! empty( $parts['path'] ) && false !== strpos( (string) $parts['path'], '/maps/embed' ) ) {
				return $url;
			}

			if ( ! empty( $parts['query'] ) ) {
				parse_str( (string) $parts['query'], $query_vars );

				if ( ! empty( $query_vars['q'] ) ) {
					return 'https://www.google.com/maps?q=' . rawurlencode( (string) $query_vars['q'] ) . '&output=embed';
				}
			}
		}

		return 'https://www.google.com/maps?q=' . rawurlencode( $url ) . '&output=embed';
	}
}
