<?php
/**
 * Product CSV import preview/apply result.
 *
 * @package Affilun\Application\Product\Csv
 */

declare(strict_types=1);

namespace Affilun\Application\Product\Csv;

/**
 * Immutable import result containing preview rows and mutation counts.
 */
final class ProductCsvImportResult {

	/**
	 * Row previews.
	 *
	 * @var list<ProductCsvImportRow>
	 */
	private array $rows;

	/**
	 * File-level validation errors.
	 *
	 * @var list<string>
	 */
	private array $errors;

	/**
	 * Number of rows created during apply.
	 */
	private int $createdCount;

	/**
	 * Number of rows updated during apply.
	 */
	private int $updatedCount;

	/**
	 * @param list<ProductCsvImportRow> $rows         Row previews.
	 * @param list<string>              $errors       File-level errors.
	 * @param int                       $createdCount Created rows.
	 * @param int                       $updatedCount Updated rows.
	 */
	public function __construct(
		array $rows = array(),
		array $errors = array(),
		int $createdCount = 0,
		int $updatedCount = 0
	) {
		$this->rows         = array_values( $rows );
		$this->errors       = array_values( $errors );
		$this->createdCount = $createdCount;
		$this->updatedCount = $updatedCount;
	}

	/**
	 * Row previews.
	 *
	 * @return list<ProductCsvImportRow>
	 */
	public function rows(): array {
		return $this->rows;
	}

	/**
	 * File-level errors.
	 *
	 * @return list<string>
	 */
	public function errors(): array {
		return $this->errors;
	}

	/**
	 * Number of data rows seen in the CSV.
	 */
	public function totalRows(): int {
		return count( $this->rows );
	}

	/**
	 * Number of valid importable rows.
	 */
	public function validRows(): int {
		$count = 0;
		foreach ( $this->rows as $row ) {
			if ( $row->isValid() ) {
				++$count;
			}
		}

		return $count;
	}

	/**
	 * Whether the file or any row has validation errors.
	 */
	public function hasErrors(): bool {
		if ( $this->errors !== array() ) {
			return true;
		}

		foreach ( $this->rows as $row ) {
			if ( ! $row->isValid() ) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Created row count.
	 */
	public function createdCount(): int {
		return $this->createdCount;
	}

	/**
	 * Updated row count.
	 */
	public function updatedCount(): int {
		return $this->updatedCount;
	}

	/**
	 * Total mutations during apply.
	 */
	public function mutatedCount(): int {
		return $this->createdCount + $this->updatedCount;
	}
}
