<?php
// DESCRIPTION: Manages backfill job state (progress, status) via WordPress options,
// providing start/cancel/complete/fail lifecycle methods for batch export jobs.

namespace SheetWise\Backfill;

class BackfillManager {

	/**
	 * Get the option key for a backfill job
	 *
	 * @since 2.0.0
	 *
	 * @param int $integration_id
	 *
	 * @return string
	 */
	private function get_option_key( $integration_id ) {
		return 'swise_backfill_' . absint( $integration_id );
	}

	/**
	 * Start a backfill job for an integration
	 *
	 * Counts total records, initializes state, and schedules the first batch.
	 *
	 * @since 2.0.0
	 *
	 * @param int    $integration_id
	 * @param string $hook The data source hook
	 *
	 * @return array The initial status
	 */
	public function start( $integration_id, $hook ) {
		$processor = new BackfillProcessor();
		$total     = $processor->count_records( $hook );

		if ( $total === 0 ) {
			return [
				'status'    => 'completed',
				'total'     => 0,
				'processed' => 0,
				'error'     => null,
			];
		}

		$state = [
			'status'     => 'running',
			'total'      => $total,
			'processed'  => 0,
			'started_at' => current_time( 'mysql' ),
			'updated_at' => current_time( 'mysql' ),
			'error'      => null,
		];

		update_option( $this->get_option_key( $integration_id ), $state, false );

		// Schedule the first batch
		$processor->schedule_next_batch( $integration_id, 0 );

		return $state;
	}

	/**
	 * Get the current status of a backfill job
	 *
	 * @since 2.0.0
	 *
	 * @param int $integration_id
	 *
	 * @return array|null Status array or null if no job exists
	 */
	public function get_status( $integration_id ) {
		return get_option( $this->get_option_key( $integration_id ), null );
	}

	/**
	 * Cancel a running backfill job
	 *
	 * @since 2.0.0
	 *
	 * @param int $integration_id
	 *
	 * @return bool
	 */
	public function cancel( $integration_id ) {
		$state = $this->get_status( $integration_id );

		if ( ! $state || $state['status'] !== 'running' ) {
			return false;
		}

		$state['status']     = 'cancelled';
		$state['updated_at'] = current_time( 'mysql' );

		return update_option( $this->get_option_key( $integration_id ), $state, false );
	}

	/**
	 * Update the processed count for a running backfill
	 *
	 * @since 2.0.0
	 *
	 * @param int $integration_id
	 * @param int $processed Total records processed so far
	 *
	 * @return void
	 */
	public function update_progress( $integration_id, $processed ) {
		$state = $this->get_status( $integration_id );

		if ( ! $state ) {
			return;
		}

		$state['processed']  = min( $processed, $state['total'] );
		$state['updated_at'] = current_time( 'mysql' );

		update_option( $this->get_option_key( $integration_id ), $state, false );
	}

	/**
	 * Mark a backfill job as completed
	 *
	 * @since 2.0.0
	 *
	 * @param int $integration_id
	 *
	 * @return void
	 */
	public function complete( $integration_id ) {
		$state = $this->get_status( $integration_id );

		if ( ! $state ) {
			return;
		}

		$state['status']     = 'completed';
		$state['processed']  = $state['total'];
		$state['updated_at'] = current_time( 'mysql' );

		update_option( $this->get_option_key( $integration_id ), $state, false );
	}

	/**
	 * Mark a backfill job as failed
	 *
	 * @since 2.0.0
	 *
	 * @param int    $integration_id
	 * @param string $error Error message
	 *
	 * @return void
	 */
	public function fail( $integration_id, $error ) {
		$state = $this->get_status( $integration_id );

		if ( ! $state ) {
			return;
		}

		$state['status']     = 'failed';
		$state['error']      = $error;
		$state['updated_at'] = current_time( 'mysql' );

		update_option( $this->get_option_key( $integration_id ), $state, false );
	}

	/**
	 * Delete the backfill state for an integration
	 *
	 * @since 2.0.0
	 *
	 * @param int $integration_id
	 *
	 * @return void
	 */
	public function cleanup( $integration_id ) {
		delete_option( $this->get_option_key( $integration_id ) );
	}
}
