<?php
/**
 * File Path: includes/import/class-mbs-importer-gs-bookshowcase.php
 *
 * MBS_Importer_GS_Bookshowcase -- Competitor WXR importer for GS Books Showcase.
 *
 * Imports books exported by the GS Books Showcase plugin (CPT: gs_bookshowcase)
 * into My Book Showroom. Handles both free-tier and Pro-tier meta fields.
 *
 * Free-tier meta keys read:
 *   _gsbks_isbn_thirteen  ISBN-13
 *   _gsbks_isbn_ten       ISBN-10 (normalised to ISBN-13 fallback)
 *   _gsbks_url            Single buy link
 *   _gsbks_publish        Publication date
 *   _gsbks_pages          Page count
 *   _gsbks_dimension      Dimensions (stored to post meta as-is)
 *
 * Pro-tier meta keys read:
 *   _gsbks_asin           ASIN (B-prefix = Kindle ebook)
 *   _gsbks_copublisher    Publisher name
 *   _gsbks_regular_price  Single price when no Pro format repeater
 *   _gsbks_sale_price     Sale price when no Pro format repeater
 *   gs_repeatable_formats PHP-serialised array of format rows:
 *                           {format_name, format_url, regular_price, sale_price}
 *   gs_repeatable_fields  PHP-serialised array of store/retailer rows:
 *                           {name, uploaded_img_id, url}
 *
 * @since  1.3.0
 * @package MyBookShowroom\Import
 *
 * Class MBS_Importer_GS_Bookshowcase
 *
 * source_key()   -- Returns 'gs-bookshowcase'.
 * target_cpt()   -- Returns 'gs_bookshowcase'.
 * map_item()     -- Maps GS Books Showcase WXR item to MBS insert_book() args.
 */

defined( 'ABSPATH' ) || exit;

/**
 * MBS_Importer_GS_Bookshowcase
 *
 * @since 1.3.0
 */
class MBS_Importer_GS_Bookshowcase extends MBS_Competitor_WXR_Base { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix

	// ── Abstract method implementations ─────────────────────────────────────

	/**
	 * @inheritDoc
	 * @return string
	 */
	protected static function source_key(): string {
		return 'gs-bookshowcase';
	}

	/**
	 * @inheritDoc
	 * @return string
	 */
	protected static function target_cpt(): string {
		return 'gs_bookshowcase';
	}

	// ── Core mapping ─────────────────────────────────────────────────────────

	/**
	 * Map a single gs_bookshowcase WXR item to MBS insert_book() argument arrays.
	 *
	 * @since  1.3.0
	 * @param  array<string, mixed> $item_data Normalised WXR item (title, content,
	 *                                          meta, categories, attachment_url).
	 * @param  array<string, mixed> $mapping   User field-mapping (unused — all
	 *                                          fields are mapped automatically).
	 * @return array{post: array, format: array, buy_links: array, post_meta: array}
	 *         Argument arrays ready for insert_book().
	 */
	protected static function map_item( array $item_data, array $mapping ): array {
		$meta  = $item_data['meta'] ?? array();
		$notes = array();

		// ── ISBN ──────────────────────────────────────────────────────────────
		// Prefer ISBN-13; fall back to ISBN-10 (normalise_isbn promotes it).
		$raw_isbn = $meta['_gsbks_isbn_thirteen'] ?? '';
		if ( '' === $raw_isbn ) {
			$raw_isbn = $meta['_gsbks_isbn_ten'] ?? '';
		}
		$isbn13 = '' !== $raw_isbn
			? MBS_ISBN_Helper::normalize_isbn( $raw_isbn )
			: '';

		// ── ASIN ─────────────────────────────────────────────────────────────
		$raw_asin = $meta['_gsbks_asin'] ?? '';
		$asin     = '' !== $raw_asin
			? MBS_ISBN_Helper::normalize_asin( $raw_asin )
			: '';

		// ── Publication date ──────────────────────────────────────────────────
		$pub_date = sanitize_text_field( $meta['_gsbks_publish'] ?? '' );

		// ── Page count ────────────────────────────────────────────────────────
		$page_length = 0;
		$raw_pages   = $meta['_gsbks_pages'] ?? '';
		if ( '' !== $raw_pages && preg_match( '/(\d+)/', $raw_pages, $pm ) ) {
			$page_length = (int) $pm[1];
		}

		// ── Publisher ─────────────────────────────────────────────────────────
		$publisher = sanitize_text_field( $meta['_gsbks_copublisher'] ?? '' );

		// ── Pro formats repeater ──────────────────────────────────────────────
		// Stored as a PHP-serialised array under 'gs_repeatable_formats'.
		// Each entry: {format_name, format_url, regular_price, sale_price}.
		$all_formats    = static::unserialize_repeater( $meta['gs_repeatable_formats'] ?? '' );
		$format_rows_gs = array_values( array_filter( $all_formats, static function ( $fr ) {
			return '' !== ( $fr['format_name'] ?? '' ) || '' !== ( $fr['format_url'] ?? '' );
		} ) );

		// ── Primary format slug ───────────────────────────────────────────────
		$format_slug = 'paperback'; // safe default
		if ( ! empty( $format_rows_gs ) ) {
			$format_slug = static::normalize_format( $format_rows_gs[0]['format_name'] ?? '' );
		}

		// ── Price ─────────────────────────────────────────────────────────────
		// Use first Pro format row's price; fall back to free-tier scalar prices.
		$price = null;
		if ( ! empty( $format_rows_gs ) ) {
			$raw_price = $format_rows_gs[0]['regular_price'] ?? '';
			if ( '' !== $raw_price ) {
				$price = floatval( $raw_price );
			}
		}
		if ( null === $price ) {
			$raw_price = $meta['_gsbks_regular_price'] ?? '';
			if ( '' !== $raw_price ) {
				$price = floatval( $raw_price );
			}
		}

		// ── Format row ────────────────────────────────────────────────────────
		// build_isbn_asin_format_rows() applies the B-ASIN gate:
		// B-ASIN + ISBN  → two rows (print + ebook)
		// numeric ASIN   → one print row
		// ISBN only      → one print row
		// neither        → paperback fallback
		$shared_format = array(
			'price' => $price,
		);
		$format_rows = static::build_isbn_asin_format_rows(
			$isbn13,
			$asin,
			$format_slug,
			$pub_date,
			$page_length,
			$shared_format
		);

		// Note additional Pro format rows that cannot be imported as separate
		// MBS format rows (they share the same ISBN/ASIN, so only the first
		// format determines the primary edition).
		for ( $i = 1; $i < count( $format_rows_gs ); $i++ ) {
			$extra_name = sanitize_text_field( $format_rows_gs[ $i ]['format_name'] ?? '' );
			if ( '' !== $extra_name ) {
				$notes[] = 'Additional format "' . $extra_name . '" could not be'
					. ' imported as a separate edition row; its purchase link has'
					. ' been preserved.';
			}
		}

		// ── Buy links ─────────────────────────────────────────────────────────
		$buy_links = array();

		// 1. From gs_repeatable_formats — each entry with a link is a buy link.
		foreach ( $format_rows_gs as $fr ) {
			$url = esc_url_raw( $fr['format_url'] ?? '' );
			if ( '' === $url ) {
				continue;
			}
			$buy_links[] = array(
				'url'          => $url,
				'retailer_key' => '',   // retailer-detector auto-detects from URL
				'label'        => sanitize_text_field( $fr['format_name'] ?? '' ),
			);
		}

		// 2. From gs_repeatable_fields — store/retailer links.
		// Each entry: {name, uploaded_img_id, url}. uploaded_img_id is an
		// attachment ID from the source site — not portable; ignored.
		$store_rows = static::unserialize_repeater( $meta['gs_repeatable_fields'] ?? '' );
		foreach ( $store_rows as $sr ) {
			$url = esc_url_raw( $sr['url'] ?? '' );
			if ( '' === $url ) {
				continue;
			}
			$buy_links[] = array(
				'url'          => $url,
				'retailer_key' => '',
				'label'        => sanitize_text_field( $sr['name'] ?? '' ),
			);
		}

		// 3. Single free-tier buy link.
		$single_url = esc_url_raw( $meta['_gsbks_url'] ?? '' );
		if ( '' !== $single_url ) {
			$buy_links[] = array(
				'url'          => $single_url,
				'retailer_key' => '',
				'label'        => '',
			);
		}

		// Deduplicate by URL — base-class helper.
		$buy_links = static::deduplicate_buy_links( $buy_links );

		// ── Post meta ─────────────────────────────────────────────────────────
		$post_meta = array();

		if ( '' !== $publisher ) {
			$post_meta['mbs_publisher'] = $publisher;
		}

		$dimension = sanitize_text_field( $meta['_gsbks_dimension'] ?? '' );
		if ( '' !== $dimension ) {
			$post_meta['mbs_dimensions'] = $dimension;
		}

		return array(
			'post'      => array(
				'post_title'   => sanitize_text_field( $item_data['title'] ?? '' ),
				'post_content' => wp_kses_post( $item_data['content'] ?? '' ),
				'post_status'  => 'publish',
				'post_type'    => 'mbs_book',
			),
			'format'    => $format_rows,
			'buy_links' => $buy_links,
			'post_meta' => $post_meta,
			'notes'     => $notes,
		);
	}
}
