<?php
/**
 * RS WP Books Showcase competitor WXR importer.
 *
 * Maps RS WP Books Showcase (CPT: book, meta prefix: _rsbs_) posts to
 * MBS books. Handles the Pro repeater fields rswpbs_book_formats and
 * rswpbs_also_available_website_list when present.
 *
 * Concrete implementation of MBS_Competitor_WXR_Base.
 *
 * source_key()   -- Returns 'rs-wp-books'.
 * target_cpt()   -- Returns 'book'.
 * map_item()     -- Maps _rsbs_* meta + Pro repeaters to MBS data array.
 *
 * CPT 'book' is unique to RS WP Books Showcase; no matches_source()
 * override is required.
 *
 * @package    MyBookShowroom
 * @subpackage Import
 * @since      1.2.0
 */

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

/**
 * Class MBS_Importer_RS_WP_Books
 *
 * Imports books exported from RS WP Books Showcase via WordPress WXR.
 *
 * @since 1.2.0
 */
class MBS_Importer_RS_WP_Books extends MBS_Competitor_WXR_Base { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix

	// ── Abstract interface ────────────────────────────────────────────────────

	/**
	 * Return the canonical source key used for telemetry and UI routing.
	 *
	 * @since  1.2.0
	 * @return string
	 */
	protected static function source_key(): string {
		return 'rs-wp-books';
	}

	/**
	 * Confirm RS WP Books Showcase source by presence of the '_rsbs_' meta prefix.
	 *
	 * C-001 fix: the 'book' CPT is now shared with Novelist. Key-inspection
	 * is required to disambiguate the two plugins during WXR analysis.
	 *
	 * @since  1.2.0
	 * @param  string[] $meta_keys All postmeta keys found in the WXR file.
	 * @return bool
	 */
	protected static function matches_source( array $meta_keys ): bool {
		foreach ( $meta_keys as $k ) {
			if ( 0 === strpos( $k, '_rsbs_' ) ) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Return the WXR post_type slug this importer targets.
	 *
	 * RS WP Books Showcase registers the 'book' CPT (singular). As of
	 * Session 133 this CPT is also used by Novelist; matches_source()
	 * above performs key-inspection disambiguation.
	 *
	 * @since  1.2.0
	 * @return string
	 */
	protected static function target_cpt(): string {
		return 'book';
	}

	// ── Field mapping ─────────────────────────────────────────────────────────

	/**
	 * Transform a raw WXR item into a normalised MBS data array.
	 *
	 * RS WP Books Showcase stores all scalar fields with the '_rsbs_' prefix.
	 * The Pro edition additionally stores two serialised repeater arrays:
	 *   - rswpbs_book_formats            { format_image, name, price, link }[]
	 *   - rswpbs_also_available_website_list { website_image, website_name, book_url }[]
	 *
	 * Buy-link priority (highest to lowest):
	 *   1. rswpbs_book_formats entries with a non-empty link.
	 *   2. rswpbs_also_available_website_list entries.
	 *   3. Single _rsbs_buy_btn_link (free-tier fallback), added only when
	 *      its URL is not already present from the repeaters above.
	 *
	 * Only the first rswpbs_book_formats entry drives the MBS format_row.
	 * Additional format entries are noted so the user can add them manually.
	 *
	 * @since  1.2.0
	 * @param  array $item_data  { title, content, post_type, meta, categories }.
	 * @return array|null  Normalised MBS data array, or null to skip.
	 */
	protected static function map_item( array $item_data ): ?array {
		$meta  = $item_data['meta'] ?? array();
		$cats  = $item_data['categories'] ?? array();
		$notes = array();

		// ── ISBN / ASIN ────────────────────────────────────────────────────────
		$raw_isbn = $meta['_rsbs_book_isbn_13'] ?? $meta['_rsbs_book_isbn'] ?? '';
		$isbn13   = '' !== $raw_isbn
			? MBS_ISBN_Helper::normalize_isbn( $raw_isbn )
			: '';

		$raw_asin = $meta['_rsbs_book_asin'] ?? '';
		$asin     = '' !== $raw_asin
			? MBS_ISBN_Helper::normalize_asin( $raw_asin )
			: '';

		// ── Page count ────────────────────────────────────────────────────────
		$page_length = absint( $meta['_rsbs_book_pages'] ?? 0 );
		if ( 0 === $page_length ) {
			// _rsbs_print_length is free-text e.g. "128 Pages" -- extract number.
			$raw_print = (string) ( $meta['_rsbs_print_length'] ?? '' );
			if ( '' !== $raw_print && preg_match( '/(\d+)/', $raw_print, $pm ) ) {
				$page_length = (int) $pm[1];
			}
		}

		// ── Publication date ──────────────────────────────────────────────────
		$pub_date = sanitize_text_field( $meta['_rsbs_book_publish_date'] ?? '' );
		if ( '' === $pub_date ) {
			$pub_date = sanitize_text_field( $meta['_rsbs_book_publish_year'] ?? '' );
		}

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

		// ── Pro formats repeater ──────────────────────────────────────────────
		// Stored as a PHP-serialised array under 'rswpbs_book_formats'.
		// PHP-serialised repeater — safe unserialise via base-class helper.
		$all_formats = static::unserialize_repeater( $meta['rswpbs_book_formats'] ?? '' );
		$format_rows = array_values( array_filter( $all_formats, static function ( $fr ) {
			return '' !== ( $fr['name'] ?? '' ) || '' !== ( $fr['link'] ?? '' );
		} ) );

		// ── Primary format slug ───────────────────────────────────────────────
		$format_slug = 'paperback'; // safe default
		if ( ! empty( $format_rows ) ) {
			$format_slug = static::normalize_format( $format_rows[0]['name'] ?? '' );
		} elseif ( '' !== ( $meta['_rsbs_book_format'] ?? '' ) ) {
			$format_slug = static::normalize_format( $meta['_rsbs_book_format'] );
		}

		// ── Format row ────────────────────────────────────────────────────────
		$format_row = array(
			'format'      => $format_slug,
			'isbn13'      => $isbn13,
			'asin'        => $asin,
			'pub_date'    => $pub_date,
			'page_length' => $page_length,
		);

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

		// 1. From rswpbs_book_formats — each entry with a link becomes a buy link.
		foreach ( $format_rows as $i => $fr ) {
			$url = esc_url_raw( $fr['link'] ?? '' );
			if ( '' === $url ) {
				continue;
			}
			$buy_links[] = array(
				'url'          => $url,
				'retailer_key' => '',   // base class auto-detects from URL
				'label'        => sanitize_text_field( $fr['name'] ?? '' ),
			);
			if ( $i > 0 ) {
				$extra   = static::normalize_format( $fr['name'] ?? '' );
				$notes[] = 'Additional format "'
					. sanitize_text_field( $fr['name'] ?? '' )
					. '" (' . $extra . ') could not be imported as a separate'
					. ' format row; its purchase link has been preserved.';
			}
		}

		// 2. From rswpbs_also_available_website_list (Pro MSL repeater).
		$msl_rows = static::unserialize_repeater( $meta['rswpbs_also_available_website_list'] ?? '' );
		foreach ( $msl_rows as $msl ) {
			$url = esc_url_raw( $msl['book_url'] ?? '' );
			if ( '' === $url ) {
				continue;
			}
			$buy_links[] = array(
				'url'          => $url,
				'retailer_key' => '',
				'label'        => sanitize_text_field( $msl['website_name'] ?? '' ),
			);
		}

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

		// 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['_rsbs_book_dimension'] ?? '' );
		if ( '' !== $dimension ) {
			$post_meta['mbs_dimensions'] = $dimension;
		}

		$weight = sanitize_text_field( $meta['_rsbs_book_weight'] ?? '' );
		if ( '' !== $weight ) {
			$post_meta['mbs_weight'] = $weight;
		}

		// Preserve ISBN-10 as a supplemental meta key (no MBS column for it).
		$isbn10 = sanitize_text_field( $meta['_rsbs_book_isbn_10'] ?? '' );
		if ( '' !== $isbn10 ) {
			$post_meta['mbs_rswpbs_isbn10'] = $isbn10;
		}

		// Availability: map _rsbs_book_availability_status → mbs_lifecycle_state.
		// 'upcoming'  → 'coming_soon'.
		// 'available' → '' (default active; hydrator treats empty as active).
		$avail = sanitize_text_field( $meta['_rsbs_book_availability_status'] ?? '' );
		if ( 'upcoming' === $avail ) {
			$post_meta['mbs_lifecycle_state'] = 'coming_soon';
		} elseif ( 'available' === $avail ) {
			$post_meta['mbs_lifecycle_state'] = '';
		}

		// ── Taxonomies ────────────────────────────────────────────────────────
		$taxonomies = array();

		foreach ( $cats as $cat ) {
			$domain = $cat['domain'] ?? '';
			$name   = sanitize_text_field( $cat['name'] ?? '' );
			if ( '' === $name ) {
				continue;
			}
			switch ( $domain ) {
				case 'book-author':
					$taxonomies[ MBS_TAX_AUTHOR ][] = $name;
					break;
				case 'book-series':
					$taxonomies[ MBS_TAX_SERIES ][] = $name;
					break;
				case 'book-category':
					$taxonomies[ MBS_TAX_GENRE ][] = $name;
					break;
				default:
					break;
			}
		}

		// Translator → contributor term.
		$translator = sanitize_text_field( $meta['_rsbs_book_translator'] ?? '' );
		if ( '' !== $translator ) {
			$taxonomies[ MBS_TAX_CONTRIBUTOR ][] = $translator;
		}

		// ── Dropped fields ─────────────────────────────────────────────────────
		// _rsbs_book_language         -- deferred to ONIX 3.0 language field.
		// _rsbs_book_country          -- no MBS equivalent.
		// _rsbs_book_file_size        -- ebook-specific technical detail.
		// _rsbs_book_file_format      -- ebook file format (PDF, ePub, etc.).
		// _rsbs_simultaneous_device_usage -- Kindle-specific.
		// _rsbs_book_text_to_speech   -- Kindle-specific.
		// _rsbs_screen_reader         -- Kindle-specific.
		// _rsbs_enhanced_typesetting  -- Kindle-specific.
		// _rsbs_x_ray                 -- Kindle-specific.
		// _rsbs_word_wise             -- Kindle-specific.
		// _rsbs_sticky_notes          -- Kindle-specific.
		// _rsbs_book_rating_links     -- external rating URL, no MBS equivalent.
		// _rsbs_total_book_ratings    -- no MBS equivalent.
		// _rsbs_average_book_rating   -- no MBS equivalent.
		// _rsbs_book_reading_age      -- no MBS equivalent.
		// _rsbs_book_grade_level      -- no MBS equivalent.
		// _rsbs_book_lexile_measure   -- no MBS equivalent.
		// _rsbs_book_reading_date     -- personal reading log, no MBS equivalent.
		// _rsbs_original_book_name    -- translation metadata, no MBS equivalent.
		// _rsbs_original_book_url     -- translation metadata, no MBS equivalent.
		// _rsbs_book_sale_price       -- pricing outside MBS scope.
		// _rsbs_book_price            -- pricing outside MBS scope.
		// rswpbs_book_formats[format_image]         -- attachment URL, site-specific.
		// rswpbs_also_available_website_list[website_image] -- attachment URL.

		return array(
			'title'      => sanitize_text_field( $item_data['title'] ?? '' ),
			'content'    => wp_kses_post( $item_data['content'] ?? '' ),
			'post_meta'  => $post_meta,
			'format_row' => $format_row,
			'buy_links'  => $buy_links,
			'taxonomies' => $taxonomies,
			'notes'      => $notes,
		);
	}

}
