<?php
/**
 * Media upload 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\Factories\ViewsFactory;
use Awesomemotive\Rewardswp\Interfaces\ViewInterface;
use function Awesomemotive\Rewardswp\Helpers\kses;

class MediaUploadComponentView extends AbstractView implements ViewInterface {

	/**
	 * Views factory instance.
	 *
	 * @since 1.0.0
	 *
	 * @var ViewsFactory
	 */
	private ViewsFactory $views_factory;

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 *
	 * @param ViewsFactory $views_factory Views factory instance.
	 */
	public function __construct( ViewsFactory $views_factory ) {
		$this->views_factory = $views_factory;
	}

	/**
	 * Render a reusable media upload component (image-only) that integrates with Alpine.
	 *
	 * Supports both direct x-model binding and parent container properties.
	 * The Alpine controller is registered in assets/js/admin/components/media-upload.js as mediaUpload.
	 *
	 * @param array $args {
	 *   @type string $label            Field label.
	 *   @type string $help_text        Optional help text below the button.
	 *   @type string $x_model_id       Alpine x-model for attachment id (e.g. 'attachmentId' or 'currentEmail.logo_attachment_id').
	 *   @type string $x_model_url      Alpine x-model for preview url (e.g. 'previewUrl' or 'currentEmail.logo_preview_url').
	 *   @type string $x_model_size     Alpine x-model for size (e.g. 'imageSize' or 'currentEmail.logo_size').
	 *   @type int    $attachment_id    Initial attachment ID (PHP fallback).
	 *   @type string $preview_url      Initial preview URL (PHP fallback).
	 *   @type string $size             Initial size (PHP fallback).
	 *   @type array  $sizes_labels     Map of size => label. Defaults to WP common sizes.
	 *   @type bool   $show_size_selector Whether to show the size selector dropdown (default true).
	 *   @type string|array $preview_size Size for image preview display (string or array of params). Defaults to $size.
	 *   @type string $button_text      Button text for initial upload.
	 *   @type string $change_text      Button text when changing image.
	 *   @type string $remove_text      Button text when removing image.
	 *   @type string $select_title     Media frame title.
	 *   @type string $select_button    Media frame button text.
	 *   @type string $x_ref            x-ref key for Alpine root reference (default 'mediaUpload').
	 * }
	 *
	 * @return void
	 */
	public function render( array $args = [] ): void {
		$args = wp_parse_args(
			$args,
			[
				'label'              => __( 'Media', 'rewardswp' ),
				'help_text'          => '',
				'x_model_id'         => '',
				'x_model_url'        => '',
				'x_model_size'       => '',
				'attachment_id'      => 0,
				'preview_url'        => '',
				'size'               => 'medium',
				'sizes_labels'       => [
					'thumbnail' => __( 'Thumbnail (150px)', 'rewardswp' ),
					'medium'    => __( 'Medium (300px)', 'rewardswp' ),
					'large'     => __( 'Large (600px)', 'rewardswp' ),
					'full'      => __( 'Full Size', 'rewardswp' ),
				],
				'show_size_selector' => false,
				'preview_size'       => null, // null means use 'size' parameter
				'button_text'        => __( 'Upload', 'rewardswp' ),
				'change_text'        => __( 'Change', 'rewardswp' ),
				'remove_text'        => __( 'Remove', 'rewardswp' ),
				'select_title'       => __( 'Select Image', 'rewardswp' ),
				'select_button'      => __( 'Use this image', 'rewardswp' ),
				'x_ref'              => 'mediaUpload',
				// Optional Alpine expression to invoke on changes (e.g. 'refreshPreview()')
				'on_change'          => '',
				'max_height_class'   => '', // Optional max-height override (e.g. 'max-h-20')
			]
		);

		// If preview_size is not set, use the size parameter
		if ( $args['preview_size'] === null ) {
			$args['preview_size'] = $args['size'];
		}

		// Generate preview URL using custom preview_size if attachment_id is set
		if ( $args['attachment_id'] && empty( $args['preview_url'] ) ) {
			$image_data = wp_get_attachment_image_src( $args['attachment_id'], $args['preview_size'] );
			if ( $image_data ) {
				$args['preview_url'] = $image_data[0];
				// Force HTTPS if current site is HTTPS to avoid Mixed Content issues
				if ( is_ssl() && strpos( $args['preview_url'], 'http://' ) === 0 ) {
					$args['preview_url'] = str_replace( 'http://', 'https://', $args['preview_url'] );
				}
			}
		}

		// Determine the size value for JavaScript based on preview_size type
		$js_size = $args['size'];
		if ( is_array( $args['preview_size'] ) ) {
			// For custom dimensions, use 'custom' as size identifier
			$js_size = 'custom';
		}

		// Prepare sizes json for Alpine (encoded safely for inline attribute use)
		$sizes_json = wp_json_encode( $args['sizes_labels'] );
		?>

		<div class="space-y-2">
			<?php if ( ! empty( $args['label'] ) ) : ?>
				<label class="block text-sm font-medium text-gray-700 mb-1">
					<?php echo esc_html( $args['label'] ); ?>
				</label>
			<?php endif; ?>

			<div
				x-ref="<?php echo esc_attr( $args['x_ref'] ); ?>"
				x-data="mediaUpload({
					ref: '<?php echo esc_attr( $args['x_ref'] ); ?>',
					xModelId: '<?php echo esc_attr( $args['x_model_id'] ); ?>',
					xModelUrl: '<?php echo esc_attr( $args['x_model_url'] ); ?>',
					xModelSize: '<?php echo esc_attr( $args['x_model_size'] ); ?>',
					initialAttachmentId: <?php echo esc_js( $args['attachment_id'] ); ?>,
					initialPreviewUrl: '<?php echo esc_js( $args['preview_url'] ); ?>',
					initialSize: '<?php echo esc_js( $js_size ); ?>',
					sizes: <?php echo esc_attr( $sizes_json ); ?>,
					selectTitle: '<?php echo esc_js( $args['select_title'] ); ?>',
					selectButton: '<?php echo esc_js( $args['select_button'] ); ?>',
					onChangeExpr: '<?php echo esc_js( $args['on_change'] ); ?>'
				})"
			>
				<!-- Upload button when empty -->
				<div x-show="!attachmentId || !previewUrl">
					<?php
					$this->views_factory->get_view( ButtonComponentView::class )->render(
						[
							'text'  => $args['button_text'],
							'type'  => 'button',
							'click' => 'openMediaUploader()',
							'style' => 'secondary',
							'size'  => 'sm',
						]
					);
					?>
					<?php if ( ! empty( $args['help_text'] ) ) : ?>
						<p class="text-xs text-gray-500 mt-2"><?php echo wp_kses( $args['help_text'], kses() ); ?></p>
					<?php endif; ?>
				</div>

				<!-- Preview + controls when has image -->
				<div x-show="attachmentId && previewUrl" class="space-y-3">
					<div class="group relative inline-block cursor-pointer overflow-hidden rounded-lg" x-on:click="openMediaUploader()">
						<img x-bind:src="previewUrl"
							alt=""
							class="max-w-xs h-auto block" />

						<!-- Hover overlay with actions -->
						<div class="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity duration-200 flex items-center justify-center">
							<span class="text-white text-sm font-medium"><?php echo esc_html( $args['change_text'] ); ?></span>
							<button type="button"
								x-on:click.stop="removeImage()"
								class="absolute top-2 right-2 p-1.5 bg-black/40 hover:bg-red-600 rounded-md text-white/80 hover:text-white transition-colors duration-150 cursor-pointer"
								title="<?php echo esc_attr( $args['remove_text'] ); ?>">
								<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path></svg>
							</button>
						</div>
					</div>

					<?php if ( $args['show_size_selector'] ) : ?>
					<div>
						<label class="block text-xs font-medium text-gray-600 mb-1"><?php esc_html_e( 'Size', 'rewardswp' ); ?></label>
						<select x-model="size"
								x-on:change="handleSizeChange($event.target.value)"
								class="w-full px-3 py-1 text-sm border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500">
							<template x-for="(label, value) in sizes" x-key="value">
								<option x-bind:value="value" x-text="label"></option>
							</template>
						</select>
					</div>
					<?php endif; ?>

					<!-- Hidden input to explicitly flag removal in forms that serialize DOM (if used) -->
					<input type="hidden" name="banner_removed" x-bind:value="(!attachmentId ? '1' : '0')">
				</div>
			</div>
		</div>
		<?php
	}
}


