<?php
/**
 * Elementor code block widget.
 *
 * @package MarkBlocks
 */

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

/**
 * Displays an editable, syntax-highlighted code block.
 */
final class MarkBlocks_Code_Block_Widget extends \Elementor\Widget_Base {
	private const MAX_CODE_BYTES = 2097152;

	/**
	 * Elementor widget identifier.
	 */
	public function get_name(): string {
		// Retained for compatibility with content created by pre-release builds.
		return 'emb_code_block';
	}

	/**
	 * Widget title shown in the Elementor panel.
	 */
	public function get_title(): string {
		return esc_html__( 'Markdown Code Block', 'markblocks' );
	}

	/**
	 * Elementor icon identifier.
	 */
	public function get_icon(): string {
		return 'eicon-editor-code';
	}

	/**
	 * Elementor categories containing this widget.
	 *
	 * @return string[]
	 */
	public function get_categories(): array {
		return [ 'markblocks-content' ];
	}

	/**
	 * Search keywords for the Elementor panel.
	 *
	 * @return string[]
	 */
	public function get_keywords(): array {
		return [ 'code', 'snippet', 'syntax', 'terminal', 'cli' ];
	}

	/**
	 * Conditional frontend script dependencies.
	 *
	 * @return string[]
	 */
	public function get_script_depends(): array {
		return [ 'markblocks-frontend' ];
	}

	/**
	 * Conditional frontend style dependencies.
	 *
	 * @return string[]
	 */
	public function get_style_depends(): array {
		return [ 'markblocks-frontend' ];
	}

	/**
	 * Avoid an unnecessary Elementor wrapper around the widget markup.
	 */
	public function has_widget_inner_wrapper(): bool {
		return false;
	}

	/**
	 * Register Elementor controls.
	 */
	protected function register_controls(): void {
		$this->start_controls_section(
			'content_section',
			[ 'label' => esc_html__( 'Code', 'markblocks' ) ]
		);

		$this->add_control(
			'code',
			[
				'label'   => esc_html__( 'Code', 'markblocks' ),
				'type'    => \Elementor\Controls_Manager::TEXTAREA,
				'rows'    => 18,
				'default' => "config system global\n    set hostname Example-FortiGate\nend",
			]
		);

		$this->add_control(
			'language',
			[
				'label'       => esc_html__( 'Language', 'markblocks' ),
				'type'        => \Elementor\Controls_Manager::TEXT,
				'default'     => 'fortios',
				'placeholder' => esc_attr__( 'bash, json, python, php, sql, fortios…', 'markblocks' ),
			]
		);

		$this->add_control(
			'filename',
			[
				'label'       => esc_html__( 'Filename or label', 'markblocks' ),
				'type'        => \Elementor\Controls_Manager::TEXT,
				'placeholder' => esc_attr__( 'config.json', 'markblocks' ),
			]
		);

		$this->add_control(
			'theme',
			[
				'label'   => esc_html__( 'Theme', 'markblocks' ),
				'type'    => \Elementor\Controls_Manager::SELECT,
				'default' => 'midnight',
				'options' => [
					'midnight' => esc_html__( 'Midnight', 'markblocks' ),
					'light'    => esc_html__( 'Light', 'markblocks' ),
				],
			]
		);

		$this->add_control(
			'show_copy',
			[
				'label'        => esc_html__( 'Copy button', 'markblocks' ),
				'type'         => \Elementor\Controls_Manager::SWITCHER,
				'return_value' => 'yes',
				'default'      => 'yes',
			]
		);

		$this->add_control(
			'wrap_lines',
			[
				'label'        => esc_html__( 'Wrap long lines', 'markblocks' ),
				'type'         => \Elementor\Controls_Manager::SWITCHER,
				'return_value' => 'yes',
				'default'      => '',
			]
		);

		$this->end_controls_section();
	}

	/**
	 * Render safe frontend markup.
	 */
	protected function render(): void {
		$settings = $this->get_settings_for_display();
		$code     = (string) ( $settings['code'] ?? '' );

		if ( strlen( $code ) > self::MAX_CODE_BYTES ) {
			echo '<p class="markblocks-markdown-error">' . esc_html__( 'Code content exceeds the 2 MB safety limit.', 'markblocks' ) . '</p>';
			return;
		}

		$language = strtolower( preg_replace( '/[^a-zA-Z0-9_+\-.#]/', '', (string) ( $settings['language'] ?? '' ) ) ?? '' );
		$language = substr( $language, 0, 64 );
		$theme    = in_array( $settings['theme'] ?? '', [ 'midnight', 'light' ], true ) ? $settings['theme'] : 'midnight';
		$label    = '' !== ( $settings['filename'] ?? '' ) ? (string) $settings['filename'] : ( '' !== $language ? strtoupper( $language ) : __( 'Code', 'markblocks' ) );
		$label    = function_exists( 'mb_substr' ) ? mb_substr( $label, 0, 200 ) : substr( $label, 0, 200 );
		$classes  = 'markblocks-code-block markblocks-theme-' . $theme . ( 'yes' === ( $settings['wrap_lines'] ?? '' ) ? ' markblocks-wrap-lines' : '' );
		?>
		<div class="<?php echo esc_attr( $classes ); ?>" data-language="<?php echo esc_attr( $language ); ?>">
			<div class="markblocks-code-toolbar">
				<span class="markblocks-code-language"><?php echo esc_html( $label ); ?></span>
				<?php if ( 'yes' === ( $settings['show_copy'] ?? 'yes' ) ) : ?>
					<button type="button" class="markblocks-copy-code" aria-label="<?php echo esc_attr__( 'Copy code', 'markblocks' ); ?>"><?php echo esc_html__( 'Copy', 'markblocks' ); ?></button>
				<?php endif; ?>
			</div>
			<pre><code class="language-<?php echo esc_attr( $language ); ?>"><?php echo esc_html( $code ); ?></code></pre>
		</div>
		<?php
	}
}
