<?php
/**
 * Wall Art Studio module.
 *
 * @package MarkPacuraAlbumBuilder
 */

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

final class MPAB_Wall_Art {
	const OPTION_KEY = 'mpab_wall_art_settings';
	const POST_TYPE  = 'mpab_wall_order';
	const TOKEN_KEY  = 'mpab_wall_art_submit';

	/** @var MPAB_Wall_Art|null */
	private static $instance = null;

	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	public static function activate() {
		if ( false === get_option( self::OPTION_KEY, false ) ) {
			add_option( self::OPTION_KEY, self::defaults(), '', false );
		}
	}

	private function __construct() {
		add_action( 'init', array( $this, 'register_order_type' ) );
		add_action( 'admin_menu', array( $this, 'register_admin_page' ), 20 );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
		add_action( 'admin_post_mpab_save_wall_art', array( $this, 'save_settings' ) );
		add_action( 'admin_post_mpab_wall_art_download', array( $this, 'download_order_file' ) );
		add_action( 'rest_api_init', array( $this, 'register_routes' ) );
		add_action( 'add_meta_boxes', array( $this, 'register_order_metabox' ) );
		add_action( 'before_delete_post', array( $this, 'delete_order_files' ) );
		add_shortcode( 'wb_studio', array( $this, 'render_studio' ) );
		add_shortcode( 'wb_wall_art', array( $this, 'render_builder' ) );
		add_filter( 'manage_' . self::POST_TYPE . '_posts_columns', array( $this, 'order_columns' ) );
		add_action( 'manage_' . self::POST_TYPE . '_posts_custom_column', array( $this, 'render_order_column' ), 10, 2 );
	}

	private static function defaults() {
		return array(
			'enabled'          => 1,
			'product_enabled'  => array( 'canvas', 'metal', 'acrylic', 'hanging-canvas', 'framed-photo' ),
			'item_enabled'     => array(),
			'item_selection_set' => 0,
			'setup_complete'    => 0,
			'markup_percent'   => 100,
			'price_overrides'  => array(),
		);
	}

	/**
	 * Build the Wall Art part of the suggested Studio offer.
	 *
	 * Existing prices and markup are deliberately preserved. Confirming the
	 * suggestion only makes the complete Wall Art catalogue available and marks
	 * that offer as reviewed.
	 *
	 * @param array $base Existing Wall Art settings.
	 * @return array<string,mixed>
	 */
	public static function suggested_offer_settings( $base ) {
		$settings = wp_parse_args( is_array( $base ) ? $base : array(), self::defaults() );
		$settings['enabled']            = 1;
		$settings['product_enabled']    = self::defaults()['product_enabled'];
		$settings['item_enabled']       = array();
		$settings['item_selection_set'] = 0;
		$settings['setup_complete']     = 1;
		return $settings;
	}

	private function settings() {
		$saved = get_option( self::OPTION_KEY, array() );
		$saved = is_array( $saved ) ? $saved : array();
		return wp_parse_args( $saved, self::defaults() );
	}

	private function catalogue() {
		static $catalogue = null;
		if ( null === $catalogue ) {
			$path = MPAB_DIR . 'assets/data/wall-art-catalogue.json';
			$catalogue = is_readable( $path ) ? json_decode( (string) file_get_contents( $path ), true ) : array();
			$catalogue = is_array( $catalogue ) ? $catalogue : array();
		}
		return $catalogue;
	}

	/** Translate the client-visible catalogue without changing stable product IDs. */
	private function translated_catalogue() {
		$catalogue = $this->catalogue();
		foreach ( isset( $catalogue['products'] ) ? $catalogue['products'] : array() as $product_index => $product ) {
			$catalogue['products'][ $product_index ]['label'] = _x( $product['label'], 'Wall art product', 'mark-pacura-album-builder' );
			$catalogue['products'][ $product_index ]['description'] = _x( $product['description'], 'Wall art product description', 'mark-pacura-album-builder' );
			$catalogue['products'][ $product_index ]['option_labels'] = array();
			foreach ( isset( $product['options'] ) ? $product['options'] : array() as $option ) {
				$catalogue['products'][ $product_index ]['option_labels'][ $option ] = _x( $option, 'Wall art finish', 'mark-pacura-album-builder' );
			}
			foreach ( isset( $product['items'] ) ? $product['items'] : array() as $item_index => $item ) {
				$catalogue['products'][ $product_index ]['items'][ $item_index ]['orientation'] = _x( $item['orientation'], 'Wall art orientation', 'mark-pacura-album-builder' );
				if ( ! empty( $item['material'] ) ) {
					$catalogue['products'][ $product_index ]['items'][ $item_index ]['material'] = _x( $item['material'], 'Wall art material', 'mark-pacura-album-builder' );
				}
			}
		}
		return $catalogue;
	}

	private function currency() {
		$album_settings = get_option( MPAB_Plugin::OPTION_KEY, array() );
		$currency = isset( $album_settings['currency'] ) ? strtoupper( sanitize_key( $album_settings['currency'] ) ) : 'GBP';
		return in_array( $currency, array( 'GBP', 'EUR', 'USD' ), true ) ? $currency : 'GBP';
	}

	/** Use the same photographer-selected brand accent as the album builder. */
	private function accent_colour() {
		$studio_settings = get_option( MPAB_Plugin::OPTION_KEY, array() );
		$accent = sanitize_hex_color( isset( $studio_settings['accent_colour'] ) ? $studio_settings['accent_colour'] : '' );
		return $accent ? $accent : '#C47750';
	}

	private function symbol( $currency ) {
		$symbols = array( 'GBP' => '£', 'EUR' => '€', 'USD' => '$' );
		return isset( $symbols[ $currency ] ) ? $symbols[ $currency ] : '£';
	}

	private function public_catalogue() {
		$source   = $this->translated_catalogue();
		$settings = $this->settings();
		$currency = $this->currency();
		$products = array();
		foreach ( isset( $source['products'] ) ? $source['products'] : array() as $product ) {
			if ( ! in_array( $product['id'], (array) $settings['product_enabled'], true ) ) {
				continue;
			}
			$items = array();
			foreach ( $product['items'] as $item ) {
				if ( ! empty( $settings['item_selection_set'] ) && ! in_array( $item['id'], (array) $settings['item_enabled'], true ) ) {
					continue;
				}
				$reference = isset( $item['reference_prices'][ $currency ] ) ? (float) $item['reference_prices'][ $currency ] : 0;
				$price = isset( $settings['price_overrides'][ $item['id'] ] ) && '' !== (string) $settings['price_overrides'][ $item['id'] ]
					? (float) $settings['price_overrides'][ $item['id'] ]
					: round( $reference * ( 1 + ( (float) $settings['markup_percent'] / 100 ) ), 2 );
				$item['price'] = $price;
				unset( $item['reference_prices'], $item['notes'] );
				$items[] = $item;
			}
			if ( $items ) {
				$product['items'] = $items;
				$products[] = $product;
			}
		}
		return array(
			'products'        => $products,
			'currency'        => $currency,
			'currency_symbol' => $this->symbol( $currency ),
			'upload'          => isset( $source['upload'] ) ? $source['upload'] : array(),
		);
	}

	public function register_order_type() {
		register_post_type(
			self::POST_TYPE,
			array(
				'labels' => array(
					'name'          => __( 'Wall art orders', 'mark-pacura-album-builder' ),
					'singular_name' => __( 'Wall art order', 'mark-pacura-album-builder' ),
					'edit_item'     => __( 'View wall art order', 'mark-pacura-album-builder' ),
				),
				'public'              => false,
				'show_ui'             => true,
				'show_in_menu'        => 'mpab',
				'supports'            => array( 'title' ),
				'capability_type'     => array( 'mpab_wall_order', 'mpab_wall_orders' ),
				'capabilities'        => array(
					'edit_post'              => MPAB_Plugin::ORDER_CAPABILITY,
					'read_post'              => MPAB_Plugin::ORDER_CAPABILITY,
					'delete_post'            => MPAB_Plugin::ORDER_CAPABILITY,
					'edit_posts'             => MPAB_Plugin::ORDER_CAPABILITY,
					'edit_others_posts'      => MPAB_Plugin::ORDER_CAPABILITY,
					'delete_posts'           => MPAB_Plugin::ORDER_CAPABILITY,
					'delete_private_posts'   => MPAB_Plugin::ORDER_CAPABILITY,
					'delete_others_posts'    => MPAB_Plugin::ORDER_CAPABILITY,
					'read_private_posts'     => MPAB_Plugin::ORDER_CAPABILITY,
					'create_posts'           => 'do_not_allow',
				),
				'map_meta_cap'        => true,
				'exclude_from_search' => true,
			)
		);
	}

	public function register_admin_page() {
		add_submenu_page(
			'mpab',
			__( 'Wall Art Studio', 'mark-pacura-album-builder' ),
			__( 'Wall Art Studio', 'mark-pacura-album-builder' ),
			'manage_options',
			'mpab-wall-art',
			array( $this, 'render_admin_page' )
		);
	}

	public function enqueue_admin_assets() {
		$page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
		if ( 'mpab-wall-art' !== $page ) {
			return;
		}
		wp_enqueue_style( 'mpab-admin', MPAB_URL . 'assets/css/admin.css', array(), MPAB_VERSION );
		wp_enqueue_script( 'mpab-wall-art-admin', MPAB_URL . 'assets/js/wall-art-admin.js', array(), MPAB_VERSION, true );
		wp_localize_script(
			'mpab-wall-art-admin',
			'MPAB_WALL_ADMIN_DATA',
			array(
				'shown'  => __( 'Shown to clients', 'mark-pacura-album-builder' ),
				'hidden' => __( 'Hidden from clients', 'mark-pacura-album-builder' ),
			)
		);
	}

	public function render_admin_page() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}
		$source   = $this->translated_catalogue();
		$settings = $this->settings();
		$currency = $this->currency();
		$symbol   = $this->symbol( $currency );
		$max_mb   = floor( wp_max_upload_size() / MB_IN_BYTES );
		$selected_items = 0;
		foreach ( isset( $source['products'] ) ? $source['products'] : array() as $product ) {
			if ( in_array( $product['id'], (array) $settings['product_enabled'], true ) ) {
				$selected_items += empty( $settings['item_selection_set'] ) ? count( $product['items'] ) : count( array_intersect( wp_list_pluck( $product['items'], 'id' ), (array) $settings['item_enabled'] ) );
			}
		}
		?>
		<div class="wrap mpab-admin-shell mpab-wall-admin">
			<a class="mpab-admin-back" href="<?php echo esc_url( admin_url( 'admin.php?page=mpab' ) ); ?>">&larr; <?php esc_html_e( 'Back to Studio home', 'mark-pacura-album-builder' ); ?></a>
			<?php MPAB_Plugin::render_studio_hero(); ?>
			<?php if ( isset( $_GET['saved'] ) ) : ?><div class="notice notice-success is-dismissible"><p><?php esc_html_e( 'Your wall art offer has been saved.', 'mark-pacura-album-builder' ); ?></p></div><?php endif; ?>

			<nav class="mpab-setup-guide mpab-wall-guide" data-wall-admin-guide aria-label="<?php esc_attr_e( 'Wall art setup', 'mark-pacura-album-builder' ); ?>"><div class="mpab-setup-guide__intro"><span class="mpab-section-kicker"><?php esc_html_e( 'Wall-art setup', 'mark-pacura-album-builder' ); ?></span><h2><?php esc_html_e( 'Five small steps, kept away from your albums', 'mark-pacura-album-builder' ); ?></h2><p><?php esc_html_e( 'Navigate through configuration steps freely. Changes are saved upon final confirmation.', 'mark-pacura-album-builder' ); ?></p></div><ol>
				<li><button type="button" data-wall-admin-step="1" aria-current="step"><span>1</span><strong><?php esc_html_e( 'Products', 'mark-pacura-album-builder' ); ?></strong><small><?php esc_html_e( 'Choose the range', 'mark-pacura-album-builder' ); ?></small></button></li>
				<li><button type="button" data-wall-admin-step="2"><span>2</span><strong><?php esc_html_e( 'Sizes', 'mark-pacura-album-builder' ); ?></strong><small><?php esc_html_e( 'Pick what to offer', 'mark-pacura-album-builder' ); ?></small></button></li>
				<li><button type="button" data-wall-admin-step="3"><span>3</span><strong><?php esc_html_e( 'Pricing', 'mark-pacura-album-builder' ); ?></strong><small><?php esc_html_e( 'Set client prices', 'mark-pacura-album-builder' ); ?></small></button></li>
				<li><button type="button" data-wall-admin-step="4"><span>4</span><strong><?php esc_html_e( 'Uploads', 'mark-pacura-album-builder' ); ?></strong><small><?php esc_html_e( 'Check the website', 'mark-pacura-album-builder' ); ?></small></button></li>
				<li><button type="button" data-wall-admin-step="5"><span>5</span><strong><?php esc_html_e( 'Review', 'mark-pacura-album-builder' ); ?></strong><small><?php esc_html_e( 'Save the offer', 'mark-pacura-album-builder' ); ?></small></button></li>
			</ol></nav>

			<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
				<input type="hidden" name="action" value="mpab_save_wall_art">
				<?php wp_nonce_field( 'mpab_save_wall_art' ); ?>

				<section class="mpab-wall-admin-panel" data-wall-admin-panel="1">
					<header class="mpab-setup-panel__header mpab-wall-step-one-header"><div><span class="mpab-section-kicker"><?php esc_html_e( 'Step 1 of 5', 'mark-pacura-album-builder' ); ?></span><h2><?php esc_html_e( 'Choose the wall art you want to sell', 'mark-pacura-album-builder' ); ?></h2><p><?php esc_html_e( 'Select the Wall Art products suitable for your studio catalog. You can modify these selections at any time.', 'mark-pacura-album-builder' ); ?></p></div><label class="mpab-wall-toggle mpab-wall-toggle--compact"><input type="checkbox" name="enabled" value="1" <?php checked( ! empty( $settings['enabled'] ) ); ?>> <span><strong><?php esc_html_e( 'Offer wall art to clients', 'mark-pacura-album-builder' ); ?></strong><small><?php esc_html_e( 'Disable this option to hide the Wall Art ordering experience from clients.', 'mark-pacura-album-builder' ); ?></small></span></label></header>
					<div class="mpab-wall-product-cards">
					<?php foreach ( isset( $source['products'] ) ? $source['products'] : array() as $product ) : ?>
						<label class="mpab-wall-product-choice"><input type="checkbox" data-wall-product-toggle value="<?php echo esc_attr( $product['id'] ); ?>" name="product_enabled[]" <?php checked( in_array( $product['id'], (array) $settings['product_enabled'], true ) ); ?>><span><i class="mpab-wall-product-choice__mockup mpab-wall-product-choice__mockup--<?php echo esc_attr( $product['mockup'] ); ?>"><b></b></i><strong><?php echo esc_html( $product['label'] ); ?></strong><small><?php echo esc_html( count( $product['items'] ) . ' ' . __( 'sizes and configurations', 'mark-pacura-album-builder' ) ); ?></small></span></label>
					<?php endforeach; ?>
					</div>
					<div class="mpab-setup-panel__actions"><button class="button button-primary" type="button" data-wall-admin-next="2"><?php esc_html_e( 'Continue to sizes', 'mark-pacura-album-builder' ); ?></button></div>
				</section>

				<section class="mpab-wall-admin-panel" data-wall-admin-panel="2" hidden>
					<header class="mpab-setup-panel__header"><span class="mpab-section-kicker"><?php esc_html_e( 'Step 2 of 5', 'mark-pacura-album-builder' ); ?></span><h2><?php esc_html_e( 'Choose the sizes your clients can order', 'mark-pacura-album-builder' ); ?></h2><p><?php esc_html_e( 'Configure size options by product line. Select all available sizes or uncheck specific options to customize.', 'mark-pacura-album-builder' ); ?></p></header>
					<?php foreach ( isset( $source['products'] ) ? $source['products'] : array() as $product ) : ?>
					<details class="mpab-wall-product-admin" data-wall-product-section="<?php echo esc_attr( $product['id'] ); ?>" open><summary><strong><?php echo esc_html( $product['label'] ); ?></strong><span><?php echo esc_html( count( $product['items'] ) . ' ' . __( 'available choices', 'mark-pacura-album-builder' ) ); ?></span></summary><div class="mpab-wall-size-actions"><button class="button" type="button" data-wall-select-sizes="all"><?php esc_html_e( 'Select all', 'mark-pacura-album-builder' ); ?></button><button class="button-link" type="button" data-wall-select-sizes="none"><?php esc_html_e( 'Clear', 'mark-pacura-album-builder' ); ?></button></div><div class="mpab-wall-table-wrap"><table class="widefat striped mpab-wall-prices"><thead><tr><th><?php esc_html_e( 'Offer', 'mark-pacura-album-builder' ); ?></th><th><?php esc_html_e( 'Size', 'mark-pacura-album-builder' ); ?></th><th><?php esc_html_e( 'Orientation', 'mark-pacura-album-builder' ); ?></th></tr></thead><tbody>
					<?php foreach ( $product['items'] as $item ) : $enabled = empty( $settings['item_selection_set'] ) || in_array( $item['id'], (array) $settings['item_enabled'], true ); ?>
					<tr><td><label class="mpab-size-toggle"><input type="checkbox" data-wall-size-toggle name="item_enabled[]" value="<?php echo esc_attr( $item['id'] ); ?>" <?php checked( $enabled ); ?>><span><?php esc_html_e( 'Include', 'mark-pacura-album-builder' ); ?></span></label></td><td><?php echo esc_html( $item['width_cm'] . 'x' . $item['height_cm'] . ' cm · ' . $item['width_in'] . 'x' . $item['height_in'] . ' in' ); ?></td><td><?php echo esc_html( $item['orientation'] ); ?></td></tr>
					<?php endforeach; ?></tbody></table></div></details>
					<?php endforeach; ?>
					<div class="mpab-setup-panel__actions"><button class="button" type="button" data-wall-admin-next="1"><?php esc_html_e( 'Back to products', 'mark-pacura-album-builder' ); ?></button><button class="button button-primary" type="button" data-wall-admin-next="3"><?php esc_html_e( 'Continue to pricing', 'mark-pacura-album-builder' ); ?></button></div>
				</section>

				<section class="mpab-wall-admin-panel" data-wall-admin-panel="3" hidden>
					<header class="mpab-setup-panel__header"><span class="mpab-section-kicker"><?php esc_html_e( 'Step 3 of 5', 'mark-pacura-album-builder' ); ?></span><h2><?php esc_html_e( 'Set the prices your clients will pay', 'mark-pacura-album-builder' ); ?></h2><p><?php esc_html_e( 'Apply a global markup percentage over base costs, then customize individual retail prices as desired.', 'mark-pacura-album-builder' ); ?></p></header>
					<div class="mpab-wall-price-rule"><label for="mpab-wall-markup"><strong><?php esc_html_e( 'Starting price rule', 'mark-pacura-album-builder' ); ?></strong></label><p><?php esc_html_e( 'Default prices calculate using this markup percentage. Explicitly entered prices take precedence.', 'mark-pacura-album-builder' ); ?></p><span><input id="mpab-wall-markup" type="number" min="0" max="1000" name="markup_percent" value="<?php echo esc_attr( $settings['markup_percent'] ); ?>"> % above WB cost</span></div>
					<?php foreach ( isset( $source['products'] ) ? $source['products'] : array() as $product ) : ?>
					<details class="mpab-wall-product-admin" data-wall-product-section="<?php echo esc_attr( $product['id'] ); ?>"><summary><strong><?php echo esc_html( $product['label'] ); ?></strong><span><?php esc_html_e( 'Client prices', 'mark-pacura-album-builder' ); ?></span></summary><div class="mpab-wall-table-wrap"><table class="widefat striped mpab-wall-prices"><thead><tr><th><?php esc_html_e( 'Size', 'mark-pacura-album-builder' ); ?></th><th><?php esc_html_e( 'WB reference', 'mark-pacura-album-builder' ); ?></th><th><?php esc_html_e( 'Your client price', 'mark-pacura-album-builder' ); ?></th></tr></thead><tbody>
					<?php foreach ( $product['items'] as $item ) : $reference = isset( $item['reference_prices'][ $currency ] ) ? (float) $item['reference_prices'][ $currency ] : 0; $override = isset( $settings['price_overrides'][ $item['id'] ] ) ? $settings['price_overrides'][ $item['id'] ] : ''; ?>
					<tr data-wall-price-row="<?php echo esc_attr( $item['id'] ); ?>"><td><?php echo esc_html( $item['width_cm'] . 'x' . $item['height_cm'] . ' cm · ' . $item['orientation'] ); ?></td><td><?php echo esc_html( $symbol . number_format_i18n( $reference, 2 ) ); ?></td><td><label class="mpab-wall-money"><span><?php echo esc_html( $symbol ); ?></span><input type="number" min="0" step="0.01" name="price_overrides[<?php echo esc_attr( $item['id'] ); ?>]" value="<?php echo esc_attr( $override ); ?>" placeholder="<?php echo esc_attr( round( $reference * ( 1 + ( (float) $settings['markup_percent'] / 100 ) ), 2 ) ); ?>"></label></td></tr>
					<?php endforeach; ?></tbody></table></div></details>
					<?php endforeach; ?>
					<div class="mpab-setup-panel__actions"><button class="button" type="button" data-wall-admin-next="2"><?php esc_html_e( 'Back to sizes', 'mark-pacura-album-builder' ); ?></button><button class="button button-primary" type="button" data-wall-admin-next="4"><?php esc_html_e( 'Check image uploads', 'mark-pacura-album-builder' ); ?></button></div>
				</section>

				<section class="mpab-wall-admin-panel" data-wall-admin-panel="4" hidden>
					<header class="mpab-setup-panel__header"><span class="mpab-section-kicker"><?php esc_html_e( 'Step 4 of 5', 'mark-pacura-album-builder' ); ?></span><h2><?php esc_html_e( 'Make sure client photographs can reach you', 'mark-pacura-album-builder' ); ?></h2><p><?php esc_html_e( 'Wall-art orders include an original JPG and the crop approved by your client.', 'mark-pacura-album-builder' ); ?></p></header>
					<div class="mpab-wall-upload-check"><span aria-hidden="true">↑</span><div><strong><?php esc_html_e( 'Current website upload limit', 'mark-pacura-album-builder' ); ?></strong><b><?php echo esc_html( $max_mb . ' MB' ); ?></b><p><?php echo esc_html( sprintf( __( 'Wall Art Studio supports JPG file uploads up to 80 MB. Your website host currently limits uploads to %d MB.', 'mark-pacura-album-builder' ), $max_mb ) ); ?></p><?php if ( $max_mb < 20 ) : ?><p class="mpab-wall-upload-check__warning"><?php esc_html_e( 'This upload limit may restrict high-resolution file submissions. Contact your hosting provider to increase maximum file upload limits.', 'mark-pacura-album-builder' ); ?></p><?php else : ?><p class="mpab-wall-upload-check__success"><?php esc_html_e( 'This limit is sufficient for initial upload testing.', 'mark-pacura-album-builder' ); ?></p><?php endif; ?></div></div>
					<div class="mpab-setup-panel__actions"><button class="button" type="button" data-wall-admin-next="3"><?php esc_html_e( 'Back to pricing', 'mark-pacura-album-builder' ); ?></button><button class="button button-primary" type="button" data-wall-admin-next="5"><?php esc_html_e( 'Review wall-art offer', 'mark-pacura-album-builder' ); ?></button></div>
				</section>

				<section class="mpab-wall-admin-panel" data-wall-admin-panel="5" hidden>
					<header class="mpab-setup-panel__header"><span class="mpab-section-kicker"><?php esc_html_e( 'Step 5 of 5', 'mark-pacura-album-builder' ); ?></span><h2><?php esc_html_e( 'Take one last look', 'mark-pacura-album-builder' ); ?></h2><p><?php esc_html_e( 'Save your configuration to activate. Existing Album settings will not be affected.', 'mark-pacura-album-builder' ); ?></p></header>
					<div class="mpab-wall-review-cards"><article><span><?php esc_html_e( 'Wall art', 'mark-pacura-album-builder' ); ?></span><strong data-wall-review-status><?php echo esc_html( ! empty( $settings['enabled'] ) ? __( 'Shown to clients', 'mark-pacura-album-builder' ) : __( 'Hidden from clients', 'mark-pacura-album-builder' ) ); ?></strong></article><article><span><?php esc_html_e( 'Products selected', 'mark-pacura-album-builder' ); ?></span><strong data-wall-review-products><?php echo esc_html( count( (array) $settings['product_enabled'] ) ); ?></strong></article><article><span><?php esc_html_e( 'Sizes selected', 'mark-pacura-album-builder' ); ?></span><strong data-wall-review-sizes><?php echo esc_html( $selected_items ); ?></strong></article><article><span><?php esc_html_e( 'Currency', 'mark-pacura-album-builder' ); ?></span><strong><?php echo esc_html( $currency ); ?></strong></article></div>
					<div class="mpab-setup-panel__actions"><button class="button" type="button" data-wall-admin-next="4"><?php esc_html_e( 'Back to upload check', 'mark-pacura-album-builder' ); ?></button><?php submit_button( __( 'Save my wall art offer', 'mark-pacura-album-builder' ), 'primary', 'submit', false ); ?></div>
				</section>
			</form>
		</div>
		<?php
	}

	public function save_settings() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'You are not allowed to change these settings.', 'mark-pacura-album-builder' ) );
		}
		check_admin_referer( 'mpab_save_wall_art' );
		$catalogue = $this->catalogue();
		$valid_products = wp_list_pluck( isset( $catalogue['products'] ) ? $catalogue['products'] : array(), 'id' );
		$valid_items = array();
		foreach ( isset( $catalogue['products'] ) ? $catalogue['products'] : array() as $product ) {
			$valid_items = array_merge( $valid_items, wp_list_pluck( $product['items'], 'id' ) );
		}
		$products = isset( $_POST['product_enabled'] ) ? array_map( 'sanitize_key', (array) wp_unslash( $_POST['product_enabled'] ) ) : array();
		$items = isset( $_POST['item_enabled'] ) ? array_map( 'sanitize_key', (array) wp_unslash( $_POST['item_enabled'] ) ) : array();
		$prices = array();
		foreach ( isset( $_POST['price_overrides'] ) ? (array) wp_unslash( $_POST['price_overrides'] ) : array() as $id => $price ) {
			$id = sanitize_key( $id );
			if ( in_array( $id, $valid_items, true ) && '' !== (string) $price ) {
				$prices[ $id ] = max( 0, round( (float) $price, 2 ) );
			}
		}
		update_option(
			self::OPTION_KEY,
			array(
				'enabled'         => isset( $_POST['enabled'] ) ? 1 : 0,
				'product_enabled' => array_values( array_intersect( $products, $valid_products ) ),
				'item_enabled'    => array_values( array_intersect( $items, $valid_items ) ),
				'item_selection_set' => 1,
				'setup_complete'   => 1,
				'markup_percent'  => min( 1000, max( 0, absint( isset( $_POST['markup_percent'] ) ? $_POST['markup_percent'] : 100 ) ) ),
				'price_overrides' => $prices,
			),
			false
		);
		wp_safe_redirect( add_query_arg( array( 'page' => 'mpab', 'mpab_wall_art_saved' => 1 ), admin_url( 'admin.php' ) ) );
		exit;
	}

	private function enqueue_assets() {
		$promotion = MPAB_Plugin::instance()->promotion_for( 'wall-art' );
		wp_enqueue_style( 'mpab-wall-art', MPAB_URL . 'assets/css/wall-art.css', array(), MPAB_VERSION );
		wp_enqueue_script( 'wb-studio-basket', MPAB_URL . 'assets/js/studio-basket.js', array(), MPAB_VERSION, true );
		wp_enqueue_script( 'mpab-wall-art', MPAB_URL . 'assets/js/wall-art.js', array( 'wb-studio-basket' ), MPAB_VERSION, true );
		wp_localize_script( 'wb-studio-basket', 'WB_STUDIO_BASKET_I18N', MPAB_Plugin::instance()->studio_basket_script_messages() );
		wp_localize_script(
			'mpab-wall-art',
			'MPAB_WALL_ART',
			array(
				'catalogue' => $this->public_catalogue(),
				'assetBase' => esc_url_raw( MPAB_URL . 'assets/images/wall-art/' ),
				'endpoint'  => esc_url_raw( rest_url( 'mpab/v1/wall-art-orders' ) ),
				'token'     => $this->submission_token(),
				'maxBytes'  => min( 80 * MB_IN_BYTES, wp_max_upload_size() ),
				'locale'    => function_exists( 'determine_locale' ) ? determine_locale() : get_locale(),
				'messages'  => $this->script_messages(),
				'promotion' => array(
					'active'   => ! empty( $promotion['active'] ),
					'percent'  => (int) $promotion['percent'],
					'endDate'  => (string) $promotion['end_date'],
					'endLabel' => (string) $promotion['end_label'],
				),
			)
		);
	}

	/** JavaScript copy for the Wall Art builder and combined Studio checkout. */
	private function script_messages() {
		return array(
			'sendingOrder' => __( 'Sending your order…', 'mark-pacura-album-builder' ),
			'orderNumber' => __( 'Order number %s.', 'mark-pacura-album-builder' ),
			'orderNumbers' => __( 'Order numbers %s.', 'mark-pacura-album-builder' ),
			'contactAfterOrder' => __( 'I will be in touch to confirm payment, production and delivery.', 'mark-pacura-album-builder' ),
			'orderFailed' => __( 'Your order could not be sent. Please check your connection and try again.', 'mark-pacura-album-builder' ),
			'confirmSendOrder' => __( 'Confirm and send order', 'mark-pacura-album-builder' ),
			'everythingIncluded' => __( 'Everything needed for this finish is already included.', 'mark-pacura-album-builder' ),
			'step' => __( 'Step %d', 'mark-pacura-album-builder' ),
			'chooseProduct' => __( 'Choose a wall art product to continue.', 'mark-pacura-album-builder' ),
			'chooseSize' => __( 'Choose a size to continue.', 'mark-pacura-album-builder' ),
			'chooseFinish' => __( 'Choose a finish to continue.', 'mark-pacura-album-builder' ),
			'addJpg' => __( 'Add a JPG before continuing.', 'mark-pacura-album-builder' ),
			'qualityTooLow' => __( 'This crop contains about %1$dx%2$d px, but the selected size needs at least %3$dx%4$d px. Reduce the zoom, choose a smaller size or use a larger photograph.', 'mark-pacura-album-builder' ),
			'invalidJpg' => __( 'Please choose a JPG within this website’s upload limit.', 'mark-pacura-album-builder' ),
			'unreadableJpg' => __( 'That JPG could not be opened. Please choose another photograph.', 'mark-pacura-album-builder' ),
			'finish' => __( 'Finish', 'mark-pacura-album-builder' ),
			'edit' => __( 'Edit', 'mark-pacura-album-builder' ),
			'product' => __( 'Product', 'mark-pacura-album-builder' ),
			'size' => __( 'Size', 'mark-pacura-album-builder' ),
			'numberCopies' => __( 'Number of copies', 'mark-pacura-album-builder' ),
			'usualTotal' => __( 'Usual total', 'mark-pacura-album-builder' ),
			'saving' => __( '%d%% saving', 'mark-pacura-album-builder' ),
			'promotionalTotal' => __( 'Promotional total', 'mark-pacura-album-builder' ),
			'total' => __( 'Total', 'mark-pacura-album-builder' ),
			'offerEnds' => __( 'Offer ends %s', 'mark-pacura-album-builder' ),
			'addingBasket' => __( 'Adding to basket…', 'mark-pacura-album-builder' ),
			'cropFailed' => __( 'The image crop could not be generated. Please re-position your photograph and try again.', 'mark-pacura-album-builder' ),
			'basketAddFailed' => __( 'This item could not be added to your basket. Please refresh the page and try again.', 'mark-pacura-album-builder' ),
			'addBasket' => __( 'Add to basket and order more', 'mark-pacura-album-builder' ),
			'updateItem' => __( 'Update item', 'mark-pacura-album-builder' ),
			'sendingChoices' => __( 'Sending your choices…', 'mark-pacura-album-builder' ),
			'choicesFailed' => __( 'Your choices could not be sent. Please check your connection and try again.', 'mark-pacura-album-builder' ),
		);
	}

	public function render_studio() {
		$settings = $this->settings();
		if ( empty( $settings['enabled'] ) ) {
			return do_shortcode( '[mp_album_builder]' );
		}
		$this->enqueue_assets();
		ob_start();
		?>
		<div class="wb-studio-choice" data-wb-studio style="--wall-accent:<?php echo esc_attr( $this->accent_colour() ); ?>">
			<div class="wb-studio-basket-bar" data-wb-basket-bar hidden><button type="button" data-wb-view-basket><?php esc_html_e( 'Your order', 'mark-pacura-album-builder' ); ?> <span data-wb-basket-count>0</span></button></div>
			<div class="wb-studio-choice__intro">
				<p class="wb-studio-eyebrow"><?php esc_html_e( 'Choose what you would like to create', 'mark-pacura-album-builder' ); ?></p>
				<h2><?php esc_html_e( 'How would you like to enjoy your photographs?', 'mark-pacura-album-builder' ); ?></h2>
			</div>
			<div class="wb-studio-choice__cards">
				<button type="button" class="wb-studio-entry" data-wb-open="albums"><span class="wb-studio-entry__mockup wb-studio-entry__mockup--album"></span><strong><?php esc_html_e( 'Albums', 'mark-pacura-album-builder' ); ?></strong><span><?php esc_html_e( 'Build a beautifully finished album, one choice at a time.', 'mark-pacura-album-builder' ); ?></span></button>
				<button type="button" class="wb-studio-entry" data-wb-open="wall-art"><span class="wb-studio-entry__mockup wb-studio-entry__mockup--wall"></span><strong><?php esc_html_e( 'Wall art', 'mark-pacura-album-builder' ); ?></strong><span><?php esc_html_e( 'Choose a print, size and finish, then add your photograph.', 'mark-pacura-album-builder' ); ?></span></button>
			</div>
			<div class="wb-studio-panel" data-wb-panel="albums" hidden><button type="button" class="wb-studio-back" data-wb-back>&larr; <?php esc_html_e( 'Back to albums or wall art', 'mark-pacura-album-builder' ); ?></button><?php echo do_shortcode( '[mp_album_builder]' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div>
			<div class="wb-studio-panel" data-wb-panel="wall-art" hidden><button type="button" class="wb-studio-back" data-wb-back>&larr; <?php esc_html_e( 'Back to albums or wall art', 'mark-pacura-album-builder' ); ?></button><?php echo $this->builder_markup(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div>
			<div class="wb-studio-panel wb-studio-basket-page" data-wb-panel="basket" hidden>
				<button type="button" class="wb-studio-back" data-wb-basket-continue>&larr; <?php esc_html_e( 'Continue shopping', 'mark-pacura-album-builder' ); ?></button>
				<div class="wb-studio-basket-page__intro"><p class="wb-studio-eyebrow"><?php esc_html_e( 'Your basket', 'mark-pacura-album-builder' ); ?></p><h2><?php esc_html_e( 'Ready to finish your order?', 'mark-pacura-album-builder' ); ?></h2><p><?php esc_html_e( 'Your selected items are saved below. Enter your contact details when ready to submit your order request.', 'mark-pacura-album-builder' ); ?></p></div>
				<form class="wb-studio-basket-checkout" data-wb-basket-form novalidate>
					<div class="wb-studio-basket" data-wb-basket-page-summary></div>
					<div class="mpab-wall-client"><label><?php esc_html_e( 'Your name', 'mark-pacura-album-builder' ); ?><input type="text" name="client_name" maxlength="120" required></label><label><?php esc_html_e( 'Email address', 'mark-pacura-album-builder' ); ?><input type="email" name="client_email" required></label><label class="mpab-wall-consent"><input type="checkbox" name="consent" required> <?php esc_html_e( 'I have checked the items in my basket and would like to confirm this order.', 'mark-pacura-album-builder' ); ?></label></div>
					<div class="mpab-wall-actions"><button type="button" class="mpab-wall-button mpab-wall-button--secondary" data-wb-basket-continue><?php esc_html_e( 'Continue shopping', 'mark-pacura-album-builder' ); ?></button><button type="submit" class="mpab-wall-button mpab-wall-button--confirm" data-wb-basket-submit><?php esc_html_e( 'Confirm and send order', 'mark-pacura-album-builder' ); ?></button></div>
					<div class="mpab-wall-error" data-wb-basket-error hidden></div>
				</form>
				<div class="mpab-wall-confirmation" data-wb-basket-confirmation hidden><span aria-hidden="true">&#10003;</span><p class="mpab-wall-kicker"><?php esc_html_e( 'Order submitted', 'mark-pacura-album-builder' ); ?></p><h2><?php esc_html_e( 'Thank you. Your complete order is safely saved.', 'mark-pacura-album-builder' ); ?></h2><p data-wb-basket-confirmation-copy></p></div>
			</div>
		</div>
		<?php
		return ob_get_clean();
	}

	public function render_builder() {
		if ( empty( $this->settings()['enabled'] ) ) {
			return '<p>' . esc_html__( 'Wall art ordering is currently unavailable.', 'mark-pacura-album-builder' ) . '</p>';
		}
		$this->enqueue_assets();
		return $this->builder_markup();
	}

	private function builder_markup() {
		$promotion = MPAB_Plugin::instance()->promotion_for( 'wall-art' );
		ob_start();
		?>
		<div class="mpab-wall-builder" data-mpab-wall-builder style="--wall-accent:<?php echo esc_attr( $this->accent_colour() ); ?>">
			<?php if ( $promotion['active'] ) : ?><aside class="mpab-wall-promotion"><strong><?php echo esc_html( sprintf( __( 'Enjoy %d%% off your wall art', 'mark-pacura-album-builder' ), $promotion['percent'] ) ); ?></strong><p><?php echo esc_html( $promotion['end_label'] ? sprintf( __( 'Confirm your order by %s to apply your promotional saving automatically.', 'mark-pacura-album-builder' ), $promotion['end_label'] ) : __( 'Your saving will be applied automatically on the final step.', 'mark-pacura-album-builder' ) ); ?></p></aside><?php endif; ?>
			<form novalidate>
				<div class="mpab-wall-progress" aria-label="<?php esc_attr_e( 'Wall art progress', 'mark-pacura-album-builder' ); ?>"><span data-wall-progress>1 / 5</span><i><b data-wall-progress-bar></b></i></div>
				<section class="mpab-wall-step is-active" data-wall-step="1">
					<p class="mpab-wall-kicker"><?php esc_html_e( 'Step 1', 'mark-pacura-album-builder' ); ?></p><h2><?php esc_html_e( 'Choose your wall art', 'mark-pacura-album-builder' ); ?></h2><p><?php esc_html_e( 'Select the display finish that best complements your photograph and space.', 'mark-pacura-album-builder' ); ?></p>
					<div class="mpab-wall-products" data-wall-products></div>
				</section>
				<section class="mpab-wall-step" data-wall-step="2" hidden>
					<p class="mpab-wall-kicker"><?php esc_html_e( 'Step 2', 'mark-pacura-album-builder' ); ?></p><h2><?php esc_html_e( 'Choose a size', 'mark-pacura-album-builder' ); ?></h2><p><?php esc_html_e( 'Select your preferred proportions, then choose the ideal size for your wall.', 'mark-pacura-album-builder' ); ?></p>
					<div class="mpab-wall-orientations" data-wall-orientations></div><div class="mpab-wall-sizes" data-wall-sizes></div>
				</section>
				<section class="mpab-wall-step" data-wall-step="3" hidden>
					<p class="mpab-wall-kicker"><?php esc_html_e( 'Step 3', 'mark-pacura-album-builder' ); ?></p><h2><?php esc_html_e( 'Choose the finishing details', 'mark-pacura-album-builder' ); ?></h2><p><?php esc_html_e( 'Only the choices available for your selected product will appear here.', 'mark-pacura-album-builder' ); ?></p>
					<div class="mpab-wall-finishes" data-wall-finishes></div>
				</section>
				<section class="mpab-wall-step" data-wall-step="4" hidden>
					<p class="mpab-wall-kicker"><?php esc_html_e( 'Step 4', 'mark-pacura-album-builder' ); ?></p><h2><?php esc_html_e( 'Add your photograph', 'mark-pacura-album-builder' ); ?></h2><p><?php esc_html_e( 'Upload a high-resolution JPG image, then adjust position and zoom to create your ideal crop.', 'mark-pacura-album-builder' ); ?></p>
					<div class="mpab-wall-upload" data-wall-dropzone tabindex="0"><input type="file" name="wall_original" accept="image/jpeg,.jpg,.jpeg" data-wall-file><div data-wall-empty><strong><?php esc_html_e( 'Drop your photograph here', 'mark-pacura-album-builder' ); ?></strong><span><?php esc_html_e( 'or click to choose a JPG', 'mark-pacura-album-builder' ); ?></span></div><canvas data-wall-canvas hidden></canvas></div>
					<div class="mpab-wall-editor" data-wall-editor hidden><label><?php esc_html_e( 'Zoom', 'mark-pacura-album-builder' ); ?><input type="range" min="1" max="3" step="0.01" value="1" data-wall-zoom></label><button type="button" data-wall-rotate><?php esc_html_e( 'Rotate', 'mark-pacura-album-builder' ); ?></button><button type="button" data-wall-reset><?php esc_html_e( 'Reset', 'mark-pacura-album-builder' ); ?></button><button type="button" data-wall-replace><?php esc_html_e( 'Replace image', 'mark-pacura-album-builder' ); ?></button></div>
					<p class="mpab-wall-quality" data-wall-quality hidden></p>
				</section>
				<section class="mpab-wall-step" data-wall-step="5" hidden>
					<p class="mpab-wall-kicker"><?php esc_html_e( 'Step 5', 'mark-pacura-album-builder' ); ?></p><h2><?php esc_html_e( 'Review your wall art', 'mark-pacura-album-builder' ); ?></h2><div class="wb-studio-basket" data-wall-basket-summary hidden></div><div class="mpab-wall-review" data-wall-review></div>
					<label class="mpab-wall-quantity"><span><?php esc_html_e( 'Number of copies', 'mark-pacura-album-builder' ); ?></span><input type="number" name="quantity" min="1" max="20" value="1" required></label>
					<div class="mpab-wall-client" data-wall-client hidden><label><?php esc_html_e( 'Your name', 'mark-pacura-album-builder' ); ?><input type="text" name="client_name" maxlength="120" required></label><label><?php esc_html_e( 'Email address', 'mark-pacura-album-builder' ); ?><input type="email" name="client_email" required></label><label class="mpab-wall-consent"><input type="checkbox" name="consent" value="1" required> <?php esc_html_e( 'I have checked my choices and would like to send this wall art order request.', 'mark-pacura-album-builder' ); ?></label></div>
				</section>
				<div class="mpab-wall-actions"><button type="button" class="mpab-wall-button mpab-wall-button--back" data-wall-prev hidden><?php esc_html_e( 'Back', 'mark-pacura-album-builder' ); ?></button><button type="button" class="mpab-wall-button" data-wall-next><?php esc_html_e( 'Continue', 'mark-pacura-album-builder' ); ?></button><button type="button" class="mpab-wall-button mpab-wall-button--secondary" data-wall-add-basket hidden><?php esc_html_e( 'Add to basket and order more', 'mark-pacura-album-builder' ); ?></button><button type="button" class="mpab-wall-button mpab-wall-button--confirm" data-wall-reveal-details hidden><?php esc_html_e( 'Confirm order', 'mark-pacura-album-builder' ); ?></button><button type="submit" class="mpab-wall-button mpab-wall-button--confirm" data-wall-submit hidden><?php esc_html_e( 'Confirm and send order', 'mark-pacura-album-builder' ); ?></button></div>
				<div class="mpab-wall-error" data-wall-error hidden></div>
			</form>
			<div class="mpab-wall-confirmation" data-wall-confirmation hidden><span aria-hidden="true">&#10003;</span><p class="mpab-wall-kicker"><?php esc_html_e( 'Order submitted', 'mark-pacura-album-builder' ); ?></p><h2><?php esc_html_e( 'Thank you. Your complete order is safely saved.', 'mark-pacura-album-builder' ); ?></h2><p data-wall-confirmation-copy></p></div>
		</div>
		<?php
		return ob_get_clean();
	}

	private function submission_token() {
		return hash_hmac( 'sha256', home_url( '/' ) . '|' . self::TOKEN_KEY, wp_salt( 'nonce' ) );
	}

	public function register_routes() {
		register_rest_route( 'mpab/v1', '/wall-art-orders', array( 'methods' => 'POST', 'callback' => array( $this, 'receive_order' ), 'permission_callback' => '__return_true' ) );
	}

	private function find_selection( $product_id, $item_id ) {
		foreach ( $this->public_catalogue()['products'] as $product ) {
			if ( $product_id !== $product['id'] ) { continue; }
			foreach ( $product['items'] as $item ) {
				if ( $item_id === $item['id'] ) { return array( $product, $item ); }
			}
		}
		return array( null, null );
	}

	public function receive_order( WP_REST_Request $request ) {
		$params = $request->get_params();
		$locale = isset( $params['locale'] ) ? sanitize_text_field( $params['locale'] ) : '';
		$supported_locales = array( 'it_IT', 'de_DE', 'sv_SE', 'es_ES', 'pl_PL', 'en_GB', 'en_US' );
		if ( ! in_array( $locale, $supported_locales, true ) ) {
			$locale = function_exists( 'determine_locale' ) ? determine_locale() : get_locale();
		}
		$switched = function_exists( 'switch_to_locale' ) && switch_to_locale( $locale );
		try {
			return $this->receive_order_in_locale( $request, $locale );
		} finally {
			if ( $switched && function_exists( 'restore_previous_locale' ) ) {
				restore_previous_locale();
			}
		}
	}

	/** Validate, store and email an order while its client locale is active. */
	private function receive_order_in_locale( WP_REST_Request $request, $locale ) {
		$params = $request->get_params();
		$files  = $request->get_file_params();
		$token = isset( $params['token'] ) ? sanitize_text_field( $params['token'] ) : '';
		if ( ! $token || ! hash_equals( $this->submission_token(), $token ) ) {
			return new WP_Error( 'mpab_wall_token', __( 'Your choices could not be verified. Please refresh the page and try again.', 'mark-pacura-album-builder' ), array( 'status' => 403 ) );
		}
		$name = sanitize_text_field( isset( $params['client_name'] ) ? $params['client_name'] : '' );
		$email = sanitize_email( isset( $params['client_email'] ) ? $params['client_email'] : '' );
		$quantity = isset( $params['quantity'] ) ? absint( $params['quantity'] ) : 1;
		if ( ! $name || ! is_email( $email ) || empty( $params['consent'] ) ) {
			return new WP_Error( 'mpab_wall_details', __( 'Please enter your name, email address, and confirmation before sending.', 'mark-pacura-album-builder' ), array( 'status' => 422 ) );
		}
		if ( $quantity < 1 || $quantity > 20 ) {
			return new WP_Error( 'mpab_wall_quantity', __( 'Choose between 1 and 20 copies.', 'mark-pacura-album-builder' ), array( 'status' => 422 ) );
		}
		$current_promotion = MPAB_Plugin::instance()->promotion_for( 'wall-art' );
		$submitted_promotion_percent = isset( $params['promotion_percent'] ) ? absint( $params['promotion_percent'] ) : 0;
		$submitted_promotion_end_date = isset( $params['promotion_end_date'] ) ? sanitize_text_field( $params['promotion_end_date'] ) : '';
		$expected_promotion_percent = $current_promotion['active'] ? (int) $current_promotion['percent'] : 0;
		$expected_promotion_end_date = $current_promotion['active'] ? (string) $current_promotion['end_date'] : '';
		if ( $submitted_promotion_percent !== $expected_promotion_percent || $submitted_promotion_end_date !== $expected_promotion_end_date ) {
			return new WP_Error( 'mpab_wall_promotion_changed', __( 'This special offer has just changed. Please refresh the page to see the latest total before sending your order.', 'mark-pacura-album-builder' ), array( 'status' => 409 ) );
		}
		list( $product, $item ) = $this->find_selection( sanitize_key( isset( $params['product'] ) ? $params['product'] : '' ), sanitize_key( isset( $params['item'] ) ? $params['item'] : '' ) );
		if ( ! $product || ! $item ) {
			return new WP_Error( 'mpab_wall_selection', __( 'Please choose an available wall art product and size.', 'mark-pacura-album-builder' ), array( 'status' => 422 ) );
		}
		$finish = sanitize_text_field( isset( $params['finish'] ) ? $params['finish'] : '' );
		if ( ! empty( $product['options'] ) && ! in_array( $finish, $product['options'], true ) ) {
			return new WP_Error( 'mpab_wall_finish', __( 'Please choose an available finish.', 'mark-pacura-album-builder' ), array( 'status' => 422 ) );
		}
		if ( empty( $files['original'] ) || empty( $files['crop'] ) ) {
			return new WP_Error( 'mpab_wall_image', __( 'Please add and position your photograph before sending.', 'mark-pacura-album-builder' ), array( 'status' => 422 ) );
		}
		foreach ( array( 'original', 'crop' ) as $file_key ) {
			$file = $files[ $file_key ];
			if ( UPLOAD_ERR_OK !== (int) $file['error'] || (int) $file['size'] > min( 80 * MB_IN_BYTES, wp_max_upload_size() ) ) {
				return new WP_Error( 'mpab_wall_upload', __( 'The photograph could not be uploaded. Please choose a JPG file under the size limit and try again.', 'mark-pacura-album-builder' ), array( 'status' => 413 ) );
			}
			$check = wp_check_filetype_and_ext( $file['tmp_name'], $file['name'], array( 'jpg|jpeg' => 'image/jpeg' ) );
			if ( 'image/jpeg' !== $check['type'] || ! @getimagesize( $file['tmp_name'] ) ) {
				return new WP_Error( 'mpab_wall_file_type', __( 'Please upload a JPG photograph.', 'mark-pacura-album-builder' ), array( 'status' => 415 ) );
			}
		}
		$crop_size = @getimagesize( $files['crop']['tmp_name'] );
		if ( ! $crop_size || $crop_size[0] < (int) $item['min_width'] || $crop_size[1] < (int) $item['min_height'] ) {
			return new WP_Error( 'mpab_wall_quality', __( 'Image resolution is too low for this display size. Please select a smaller product size or upload a higher-resolution photograph.', 'mark-pacura-album-builder' ), array( 'status' => 422 ) );
		}
		$reference = MPAB_Plugin::instance()->next_studio_order_reference();
		$post_id = wp_insert_post( array( 'post_type' => self::POST_TYPE, 'post_status' => 'private', 'post_title' => sprintf( __( 'Wall art order %1$s — %2$s', 'mark-pacura-album-builder' ), $reference, $name ) ), true );
		if ( is_wp_error( $post_id ) ) { return $post_id; }
		$stored = $this->store_files( $post_id, $reference, $files );
		if ( is_wp_error( $stored ) ) { wp_delete_post( $post_id, true ); return $stored; }
		$promotion_totals = MPAB_Plugin::instance()->promotion_totals_for( (float) $item['price'] * $quantity, 'wall-art' );
		$config = array(
			'product' => array( 'id' => $product['id'], 'label' => $product['label'] ),
			'item' => $item,
			'finish' => isset( $product['option_labels'][ $finish ] ) ? $product['option_labels'][ $finish ] : $finish,
			'quantity' => $quantity,
			'normal_total' => $promotion_totals['normal_total'],
			'promotion' => array(
				'applied'   => $promotion_totals['active'],
				'percent'   => $promotion_totals['percent'],
				'discount'  => $promotion_totals['discount'],
				'end_date'  => $promotion_totals['end_date'],
				'end_label' => $promotion_totals['end_label'],
			),
			'total' => $promotion_totals['total'],
			'currency_symbol' => $this->public_catalogue()['currency_symbol'],
		);
		update_post_meta( $post_id, '_mpab_reference', $reference );
		update_post_meta( $post_id, '_mpab_client_name', $name );
		update_post_meta( $post_id, '_mpab_client_email', $email );
		update_post_meta( $post_id, '_mpab_locale', $locale );
		update_post_meta( $post_id, '_mpab_configuration', wp_json_encode( $config ) );
		update_post_meta( $post_id, '_mpab_wall_files', $stored );
		update_post_meta( $post_id, '_mpab_status', 'new' );
		$this->send_emails( $post_id, $reference, $name, $email, $config );
		return rest_ensure_response( array( 'reference' => $reference, 'message' => __( 'Your wall art choices have been saved.', 'mark-pacura-album-builder' ) ) );
	}

	private function storage_root() {
		$preferred = trailingslashit( dirname( ABSPATH ) ) . 'mpab-private-wall-art';
		if ( ! is_dir( $preferred ) ) { wp_mkdir_p( $preferred ); }
		if ( is_dir( $preferred ) && is_writable( $preferred ) ) { return $preferred; }
		$fallback = trailingslashit( WP_CONTENT_DIR ) . 'mpab-private-wall-art';
		wp_mkdir_p( $fallback );
		return $fallback;
	}

	private function store_files( $post_id, $reference, $files ) {
		$root = $this->storage_root();
		if ( ! is_dir( $root ) || ! is_writable( $root ) ) {
			return new WP_Error( 'mpab_wall_storage', __( 'Unable to create secure storage for the uploaded image file. Please notify the photographer.', 'mark-pacura-album-builder' ), array( 'status' => 500 ) );
		}
		@file_put_contents( trailingslashit( $root ) . '.htaccess', "Require all denied\nDeny from all\n" );
		@file_put_contents( trailingslashit( $root ) . 'index.php', "<?php exit;\n" );
		$folder = trailingslashit( $root ) . $post_id . '-' . wp_generate_password( 20, false, false );
		if ( ! wp_mkdir_p( $folder ) ) { return new WP_Error( 'mpab_wall_storage', __( 'Image upload directory creation failed.', 'mark-pacura-album-builder' ), array( 'status' => 500 ) ); }
		$result = array();
		foreach ( array( 'original', 'crop' ) as $key ) {
			$path = trailingslashit( $folder ) . sanitize_file_name( $reference . '-' . $key . '.jpg' );
			if ( ! move_uploaded_file( $files[ $key ]['tmp_name'], $path ) ) { return new WP_Error( 'mpab_wall_store_file', __( 'The uploaded image file could not be saved.', 'mark-pacura-album-builder' ), array( 'status' => 500 ) ); }
			$result[ $key ] = $path;
		}
		return $result;
	}

	private function send_emails( $post_id, $reference, $name, $email, $config ) {
		MPAB_Plugin::instance()->send_wall_art_order_emails( $post_id, $reference, $name, $email, $config, admin_url( 'post.php?post=' . absint( $post_id ) . '&action=edit' ) );
	}

	public function register_order_metabox() {
		add_meta_box( 'mpab-wall-order', __( 'Wall art order details', 'mark-pacura-album-builder' ), array( $this, 'render_order_metabox' ), self::POST_TYPE, 'normal', 'high' );
	}

	public function render_order_metabox( $post ) {
		$config = json_decode( (string) get_post_meta( $post->ID, '_mpab_configuration', true ), true );
		$config = is_array( $config ) ? $config : array();
		$files = get_post_meta( $post->ID, '_mpab_wall_files', true );
		$rows = array(
			__( 'Order number', 'mark-pacura-album-builder' ) => get_post_meta( $post->ID, '_mpab_reference', true ),
			__( 'Client', 'mark-pacura-album-builder' ) => get_post_meta( $post->ID, '_mpab_client_name', true ),
			__( 'Email', 'mark-pacura-album-builder' ) => get_post_meta( $post->ID, '_mpab_client_email', true ),
			__( 'Product', 'mark-pacura-album-builder' ) => isset( $config['product']['label'] ) ? $config['product']['label'] : '',
			__( 'Size', 'mark-pacura-album-builder' ) => isset( $config['item'] ) ? $config['item']['width_cm'] . 'x' . $config['item']['height_cm'] . ' cm · ' . $config['item']['width_in'] . 'x' . $config['item']['height_in'] . ' in' : '',
			__( 'Finish', 'mark-pacura-album-builder' ) => isset( $config['finish'] ) ? $config['finish'] : '',
			__( 'Number of copies', 'mark-pacura-album-builder' ) => isset( $config['quantity'] ) ? absint( $config['quantity'] ) : 1,
			__( 'Total', 'mark-pacura-album-builder' ) => isset( $config['total'] ) ? $config['currency_symbol'] . number_format_i18n( $config['total'], 2 ) : '',
		);
		echo '<table class="widefat striped"><tbody>';
		foreach ( $rows as $label => $value ) { if ( '' !== (string) $value ) { echo '<tr><th style="width:180px">' . esc_html( $label ) . '</th><td>' . esc_html( $value ) . '</td></tr>'; } }
		echo '</tbody></table><p>';
		foreach ( array( 'original' => __( 'Download original', 'mark-pacura-album-builder' ), 'crop' => __( 'Download approved crop', 'mark-pacura-album-builder' ) ) as $kind => $label ) {
			if ( ! empty( $files[ $kind ] ) ) {
				$url = wp_nonce_url( add_query_arg( array( 'action' => 'mpab_wall_art_download', 'post_id' => $post->ID, 'kind' => $kind ), admin_url( 'admin-post.php' ) ), 'mpab_wall_download_' . $post->ID . '_' . $kind );
				echo '<a class="button" style="margin-right:8px" href="' . esc_url( $url ) . '">' . esc_html( $label ) . '</a>';
			}
		}
		echo '</p>';
	}

	public function download_order_file() {
		$post_id = isset( $_GET['post_id'] ) ? absint( $_GET['post_id'] ) : 0;
		$kind = isset( $_GET['kind'] ) ? sanitize_key( $_GET['kind'] ) : '';
		if ( ! $post_id || self::POST_TYPE !== get_post_type( $post_id ) || ! current_user_can( 'edit_post', $post_id ) || ! in_array( $kind, array( 'original', 'crop' ), true ) ) { wp_die( esc_html__( 'You cannot download this file.', 'mark-pacura-album-builder' ) ); }
		check_admin_referer( 'mpab_wall_download_' . $post_id . '_' . $kind );
		$files = get_post_meta( $post_id, '_mpab_wall_files', true );
		$path = isset( $files[ $kind ] ) ? $files[ $kind ] : '';
		if ( ! $path || ! is_readable( $path ) ) { wp_die( esc_html__( 'This file is no longer available.', 'mark-pacura-album-builder' ) ); }
		nocache_headers(); header( 'Content-Type: image/jpeg' ); header( 'Content-Disposition: attachment; filename="' . sanitize_file_name( get_post_meta( $post_id, '_mpab_reference', true ) . '-' . $kind . '.jpg' ) . '"' ); header( 'Content-Length: ' . filesize( $path ) ); readfile( $path ); exit;
	}

	public function delete_order_files( $post_id ) {
		if ( self::POST_TYPE !== get_post_type( $post_id ) ) { return; }
		$files = get_post_meta( $post_id, '_mpab_wall_files', true );
		foreach ( is_array( $files ) ? $files : array() as $path ) { if ( is_string( $path ) && is_file( $path ) ) { wp_delete_file( $path ); } }
		if ( ! empty( $files ) ) { $folder = dirname( reset( $files ) ); if ( is_dir( $folder ) ) { @rmdir( $folder ); } }
	}

	public function order_columns( $columns ) {
		return array( 'cb' => isset( $columns['cb'] ) ? $columns['cb'] : '', 'title' => __( 'Order', 'mark-pacura-album-builder' ), 'mpab_wall_client' => __( 'Client', 'mark-pacura-album-builder' ), 'mpab_wall_product' => __( 'Product', 'mark-pacura-album-builder' ), 'mpab_wall_total' => __( 'Total', 'mark-pacura-album-builder' ), 'date' => __( 'Date', 'mark-pacura-album-builder' ) );
	}

	public function render_order_column( $column, $post_id ) {
		$config = json_decode( (string) get_post_meta( $post_id, '_mpab_configuration', true ), true );
		if ( 'mpab_wall_client' === $column ) { echo esc_html( get_post_meta( $post_id, '_mpab_client_name', true ) ); }
		if ( 'mpab_wall_product' === $column ) { echo esc_html( isset( $config['product']['label'] ) ? $config['product']['label'] : '' ); }
		if ( 'mpab_wall_total' === $column ) { echo esc_html( isset( $config['total'] ) ? $config['currency_symbol'] . number_format_i18n( $config['total'], 2 ) : '' ); }
	}
}
