<?php
/**
 * Button component view.
 *
 * @package Awesomemotive\Rewardswp\Views\Admin\Components
 * @since 1.0.0
 */

namespace Awesomemotive\Rewardswp\Views\Admin\Components;

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

use Awesomemotive\Rewardswp\Abstracts\AbstractView;
use Awesomemotive\Rewardswp\Interfaces\ViewInterface;
use function Awesomemotive\Rewardswp\Helpers\kses;
use function Awesomemotive\Rewardswp\Helpers\tag_attr;


/**
 * Button Component View.
 *
 * @since 1.0.0
 */
class ButtonComponentView extends AbstractView implements ViewInterface {

	/**
	 * Button sizes and their corresponding classes
	 *
	 * @since 1.0.0
	 * @var array
	 */
	protected $button_sizes = [
		'xs' => 'px-2 py-1 text-xs rounded-md',
		'sm' => 'px-3 py-1.5 text-sm rounded-md',
		'md' => 'px-6 py-2.5 text-sm rounded-lg',
		'lg' => 'px-4 py-2 text-base rounded-md',
		'xl' => 'px-6 py-3 text-base rounded-md',
	];

	/**
	 * Render the template.
	 *
	 * @since 1.0.0
	 *
	 * @param array $args
	 *
	 * @return void
	 */
	public function render( array $args = [] ): void {
		$args = wp_parse_args(
			$args,
			[
				'text'               => '',
				'href'               => '',
				'type'               => 'anchor',
				'click'              => '',
				'style'              => 'primary',
				'size'               => 'md',
				'additional_classes' => '',
				'loading_state'      => false,
				'x-bind:disabled'    => '',
				'target'             => '',
				'rel'                => '',
			]
		);

		// Get size classes.
		$size_classes = isset( $this->button_sizes[ $args['size'] ] ) ? $this->button_sizes[ $args['size'] ] : $this->button_sizes['md'];

		// Base classes without layout and size.
		$base_classes = $size_classes . ' font-semibold shadow-sm cursor-pointer items-center transition-colors duration-150';

		// Style classes.
		if ( 'primary' === $args['style'] ) {
			$base_classes .= ' text-white bg-blue-600 border border-transparent hover:bg-blue-700 focus:ring-blue-500 focus:outline-none focus:ring-2 focus:ring-offset-2';
		} else {
			$base_classes .= ' bg-white text-gray-900 shadow-xs ring-1 ring-inset ring-gray-300 hover:bg-gray-50';
		}

		// Layout classes - use grid if loading state is present, otherwise use flex.
		$layout_classes   = $args['loading_state']
			? 'grid grid-cols-1 grid-rows-1 [grid-template-areas:stack] place-items-center'
			: 'inline-flex justify-center';
		$disabled_classes = 'cursor-not-allowed hover:cursor-not-allowed';

		$classes = $layout_classes . ' ' . $base_classes . ' ' . $args['additional_classes'];

		if ( 'anchor' === $args['type'] ) {
			$anchor_attrs = [];
			$target       = $args['target'];
			$rel          = $args['rel'];

			// Auto-detect external links and add target="_blank" if not set.
			if ( empty( $target ) && ! empty( $args['href'] ) ) {
				$is_external = $this->is_external_url( $args['href'] );
				if ( $is_external ) {
					$target = '_blank';
				}
			}

			// Add target attribute if set.
			if ( ! empty( $target ) ) {
				$anchor_attrs[] = tag_attr( 'target', $target, true, false );

				// Auto-add security rel if target="_blank" and rel not explicitly set.
				if ( '_blank' === $target && empty( $rel ) ) {
					$rel = 'noopener noreferrer';
				}
			}

			// Add rel attribute if set.
			if ( ! empty( $rel ) ) {
				$anchor_attrs[] = tag_attr( 'rel', $rel, true, false );
			}

			$anchor_attr_html = implode( '', $anchor_attrs );

			printf(
				'<a href="%s" class="%s"%s>%s</a>',
				esc_url( $args['href'] ),
				esc_attr( $classes ),
				wp_kses_data( $anchor_attr_html ),
				wp_kses( $this->get_button_content( $args ), kses() )
			);
		} else {
			$click_attr = $args['click'] ? tag_attr( 'x-on:click', $args['click'], true, false ) : '';
			$type       = 'submit' === $args['type'] ? 'submit' : 'button';

			$disabled_prop = tag_attr( 'x-bind:disabled', $args['x-bind:disabled'], true, false );

			$disabled_class_condition = 'false';

			if ( is_bool( $args['x-bind:disabled'] ) ) {
				$disabled_class_condition = true === $args['x-bind:disabled']
					? 'true'
					: 'false';
			}

			if ( $args['x-bind:disabled'] && is_string( $args['x-bind:disabled'] ) ) {
				$disabled_class_condition = sanitize_text_field( $args['x-bind:disabled'] );
			}

			$bind_class_value = sprintf(
				'{ \'%s\': %s }',
				$disabled_classes,
				$disabled_class_condition
			);

			printf(
				'<button x-bind:class="%s" type="%s" class="%s"%s%s>%s</button>',
				esc_attr( $bind_class_value ),
				esc_attr( $type ),
				esc_attr( $classes ),
				wp_kses_data( $click_attr ),
				wp_kses_data( $disabled_prop ),
				wp_kses( $this->get_button_content( $args ), kses() )
			);
		}
	}

	/**
	 * Check if a URL is external (different domain than current site).
	 *
	 * @since 1.0.0
	 *
	 * @param string $url URL to check.
	 * @return bool True if external, false if internal.
	 */
	private function is_external_url( string $url ): bool {
		// Parse the URL.
		$parsed_url = wp_parse_url( $url );

		// If no host, it's a relative URL (internal).
		if ( empty( $parsed_url['host'] ) ) {
			return false;
		}

		// Get current site host.
		$site_host = wp_parse_url( home_url(), PHP_URL_HOST );

		// Compare hosts.
		return $parsed_url['host'] !== $site_host;
	}

	/**
	 * Get the button content including text and spinner if enabled.
	 *
	 * @param array $args Button arguments.
	 * @return string
	 */
	private function get_button_content( array $args ): string {
		$content       = '';
		$loading_state = $args['loading_state'] ?? false;

		if ( $loading_state ) {
			// Text content with grid layout.
			$content .= sprintf(
				'<span class="[grid-area:stack] transition-opacity duration-200" x-bind:class="{ \'opacity-0\': %1$s, \'opacity-100\': !(%1$s) }">%2$s</span>
					<svg class="animate-spin h-5 w-5 [grid-area:stack] transition-opacity duration-200 hidden" x-bind:class="{ \'hidden\': !(%1$s), \'block\': %1$s }" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>',
				esc_attr( $loading_state ),
				wp_kses( $args['text'], kses() )
			);
		} elseif ( strpos( $args['text'], 'x-text=' ) !== false ) {
				$content .= sprintf( '<span %s></span>', $args['text'] );
		} else {
			$content .= wp_kses( $args['text'], kses() );
		}

		return $content;
	}
}
