<?php

namespace SugarCalendarBookings\Migration;

/**
 * Migration Report.
 *
 * Generates detailed migration reports with statistics.
 *
 * @since 1.3.0
 */
class MigrationReport {

	/**
	 * Report data.
	 *
	 * @since 1.3.0
	 *
	 * @var array<string, mixed>
	 */
	private $data = [];

	/**
	 * Constructor.
	 *
	 * @since 1.3.0
	 */
	public function __construct() {

		$this->reset();
	}

	/**
	 * Reset the report.
	 *
	 * @since 1.3.0
	 */
	public function reset() {

		$this->data = [
			'total'           => 0,
			'migrated'        => 0,
			'skipped'         => 0,
			'failed'          => 0,
			'images_migrated' => 0,
			'images_failed'   => 0,
			'errors'          => [],
			'warnings'        => [],
			'start_time'      => 0,
			'end_time'        => 0,
			'duration'        => 0,
		];
	}

	/**
	 * Start the report timer.
	 *
	 * @since 1.3.0
	 */
	public function start() {

		$this->data['start_time'] = microtime( true );
	}

	/**
	 * Stop the report timer.
	 *
	 * @since 1.3.0
	 */
	public function stop() {

		$this->data['end_time'] = microtime( true );
		$this->data['duration'] = $this->data['end_time'] - $this->data['start_time'];
	}

	/**
	 * Set total records.
	 *
	 * @since 1.3.0
	 *
	 * @param int $total Total records.
	 */
	public function set_total( $total ) {

		$this->data['total'] = (int) $total;
	}

	/**
	 * Increment migrated count.
	 *
	 * @since 1.3.0
	 */
	public function increment_migrated() {

		++$this->data['migrated'];
	}

	/**
	 * Add to migrated count.
	 *
	 * @since 1.3.0
	 *
	 * @param int $count Number to add.
	 */
	public function add_migrated( int $count ) {

		$this->data['migrated'] += $count;
	}

	/**
	 * Increment skipped count.
	 *
	 * @since 1.3.0
	 */
	public function increment_skipped() {

		++$this->data['skipped'];
	}

	/**
	 * Add to skipped count.
	 *
	 * @since 1.3.0
	 *
	 * @param int $count Number to add.
	 */
	public function add_skipped( int $count ) {

		$this->data['skipped'] += $count;
	}

	/**
	 * Increment failed count.
	 *
	 * @since 1.3.0
	 */
	public function increment_failed() {

		++$this->data['failed'];
	}

	/**
	 * Add to failed count.
	 *
	 * @since 1.3.0
	 *
	 * @param int $count Number to add.
	 */
	public function add_failed( int $count ) {

		$this->data['failed'] += $count;
	}

	/**
	 * Increment images migrated count.
	 *
	 * @since 1.3.0
	 */
	public function increment_images_migrated() {

		++$this->data['images_migrated'];
	}

	/**
	 * Increment images failed count.
	 *
	 * @since 1.3.0
	 */
	public function increment_images_failed() {

		++$this->data['images_failed'];
	}

	/**
	 * Add an error.
	 *
	 * @since 1.3.0
	 *
	 * @param string $message Error message.
	 * @param mixed  $context Error context.
	 */
	public function add_error( $message, $context = null ) {

		$this->data['errors'][] = [
			'message' => $message,
			'context' => $context,
		];
	}

	/**
	 * Add a warning.
	 *
	 * @since 1.3.0
	 *
	 * @param string $message Warning message.
	 * @param mixed  $context Warning context.
	 */
	public function add_warning( $message, $context = null ) {

		$this->data['warnings'][] = [
			'message' => $message,
			'context' => $context,
		];
	}

	/**
	 * Get the report data.
	 *
	 * @since 1.3.0
	 *
	 * @return array<string, mixed>
	 */
	public function get_data() {

		return $this->data;
	}

	/**
	 * Get a summary string.
	 *
	 * @since 1.3.0
	 *
	 * @return string
	 */
	public function get_summary() {

		return sprintf(
			'Total: %1$d | Migrated: %2$d | Skipped: %3$d | Failed: %4$d | Duration: %5$.2fs',
			$this->data['total'],
			$this->data['migrated'],
			$this->data['skipped'],
			$this->data['failed'],
			$this->data['duration']
		);
	}

	/**
	 * Check if there are any errors.
	 *
	 * @since 1.3.0
	 *
	 * @return bool
	 */
	public function has_errors() {

		return ! empty( $this->data['errors'] );
	}

	/**
	 * Check if there are any warnings.
	 *
	 * @since 1.3.0
	 *
	 * @return bool
	 */
	public function has_warnings() {

		return ! empty( $this->data['warnings'] );
	}
}
