<?php
/**
 * File Path: includes/import/csv/class-mbs-child-importer-csv-map.php
 *
 * CSV Importer – Map Child Class
 *
 * Handles all column-mapping and row-mapping logic that was previously
 * inside the monolithic class-mbs-importer-csv.php.
 *
 * Delegates constants and shared helpers to MBS_Child_Importer_CSV_Helpers.
 *
 * @package MyBookShowroom
 * @since   1.0.0
 */

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

/**
 * Child class responsible for CSV column mapping and row mapping logic.
 */
class MBS_Child_Importer_CSV_Map { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix

	/**
	 * Build the field map from CSV headers and optional user column map.
	 *
	 * @param array $headers    Lowercased CSV header row.
	 * @param array $column_map User-provided column → MBS field map.
	 * @return array            Index → field name map.
	 */
	public static function build_field_map( array $headers, array $column_map ): array {
		$field_map      = array();
		$normalized_map = array();

		foreach ( $column_map as $csv_col => $mbs_field ) {
			$normalized_map[ strtolower( trim( $csv_col ) ) ] = sanitize_key( $mbs_field );
		}

		foreach ( $headers as $index => $header ) {
			if ( str_starts_with( $header, '_' ) ) {
				// Private passthrough columns (e.g. _buy_links, _endorsements).
				// Always passthrough regardless of column_map — checked first so a
				// stale or missing column_map entry cannot suppress the passthrough.
				$field_map[ $index ] = $header;
			} elseif ( isset( $normalized_map[ $header ] ) && '' !== $normalized_map[ $header ] ) {
				$field_map[ $index ] = $normalized_map[ $header ];
			} elseif ( in_array( $header, MBS_Child_Importer_CSV_Helpers::get_accepted_columns(), true ) ) {
				$field_map[ $index ] = $header;
			}
		}

		return $field_map;
	}

	/**
	 * Map a single CSV row into a candidate array.
	 *
	 * @param array $row       One data row from CSV.
	 * @param array $field_map Index → field name map.
	 * @param int   $line      Current line number (for error reporting).
	 * @return ?array          Candidate array or null if no title.
	 */
	public static function map_row( array $row, array $field_map, int $line ): ?array {
		$candidate = array( '_line' => $line );

		foreach ( $field_map as $index => $field ) {
			$raw_value           = isset( $row[ $index ] ) ? trim( $row[ $index ] ) : '';
			$candidate[ $field ] = $raw_value;
		}

		if ( empty( $candidate['title'] ) ) {
			return null;
		}

		if ( ! empty( $candidate['isbn13'] ) ) {
			$normalized            = MBS_ISBN_Helper::normalize_isbn( $candidate['isbn13'] );
			$candidate['isbn13']   = $normalized ?: '';
		}

		return $candidate;
	}
}
