<?php
/**
 * WP-CLI commands: wp datastream <command>.
 *
 * @package DataStream
 */

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

if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
	return;
}

/**
 * Sync external APIs into WordPress and manage DataStream streams.
 */
class DataStream_CLI {

	/**
	 * Run a sync now.
	 *
	 * ## OPTIONS
	 *
	 * [--stream=<id>]
	 * : Sync only this stream.
	 *
	 * ## EXAMPLES
	 *
	 *     wp datastream sync
	 *     wp datastream sync --stream=products
	 *
	 * @param array<int, string>    $args       Positional args.
	 * @param array<string, string> $assoc_args Flags.
	 */
	public function sync( $args, $assoc_args ) {
		$stream = (string) ( $assoc_args['stream'] ?? '' );
		$result = DataStream_Engine::get_instance()->run_ingestion_sync( true, $stream );

		foreach ( (array) ( $result['streams'] ?? array() ) as $id => $detail ) {
			WP_CLI::log( sprintf( '%s: %s', $id, (string) ( $detail['message'] ?? '' ) ) );
		}

		if ( ! empty( $result['success'] ) ) {
			WP_CLI::success( sprintf( '%d records processed in %d ms.', (int) $result['processed'], (int) ( $result['duration_ms'] ?? 0 ) ) );
			return;
		}

		WP_CLI::error( (string) ( $result['message'] ?? 'Sync failed.' ) );
	}

	/**
	 * Show sync status and health.
	 *
	 * @param array<int, string>    $args       Positional args.
	 * @param array<string, string> $assoc_args Flags.
	 */
	public function status( $args, $assoc_args ) {
		$health = DataStream_Health::get_report();

		WP_CLI::log( 'Records:   ' . (int) $health['record_count'] );
		WP_CLI::log( 'Last sync: ' . ( $health['last_sync'] ?: 'never' ) );
		WP_CLI::log( 'Next sync: ' . ( $health['next_sync'] ? $health['next_sync'] . ' UTC' : 'not scheduled' ) );

		foreach ( (array) $health['stream_counts'] as $type => $count ) {
			WP_CLI::log( sprintf( '  %s: %d', $type, (int) $count ) );
		}

		foreach ( (array) $health['warnings'] as $warning ) {
			WP_CLI::warning( $warning );
		}

		$health['healthy'] ? WP_CLI::success( 'Healthy.' ) : WP_CLI::error( implode( ' ', (array) $health['issues'] ) );
	}

	/**
	 * List configured streams.
	 *
	 * ## OPTIONS
	 *
	 * [--format=<format>]
	 * : table, json, csv, yaml. Default table.
	 *
	 * @subcommand streams
	 *
	 * @param array<int, string>    $args       Positional args.
	 * @param array<string, string> $assoc_args Flags.
	 */
	public function streams( $args, $assoc_args ) {
		$rows = array();

		foreach ( DataStream_Streams::get_streams() as $stream ) {
			$rows[] = array(
				'id'      => $stream['id'],
				'label'   => $stream['label'],
				'enabled' => $stream['enabled'] ? 'yes' : 'no',
				'url'     => $stream['api_url'],
				'posts'   => $stream['post_type'] ?: '—',
				'backoff' => $stream['backoff_until'] > time() ? gmdate( 'H:i', $stream['backoff_until'] ) . ' UTC' : '—',
			);
		}

		if ( empty( $rows ) ) {
			WP_CLI::log( 'No streams configured.' );
			return;
		}

		\WP_CLI\Utils\format_items( $assoc_args['format'] ?? 'table', $rows, array( 'id', 'label', 'enabled', 'url', 'posts', 'backoff' ) );
	}

	/**
	 * Delete synced records.
	 *
	 * ## OPTIONS
	 *
	 * [--stream=<id>]
	 * : Only records from this stream.
	 *
	 * [--yes]
	 * : Skip the confirmation prompt.
	 *
	 * @param array<int, string>    $args       Positional args.
	 * @param array<string, string> $assoc_args Flags.
	 */
	public function purge( $args, $assoc_args ) {
		$stream = (string) ( $assoc_args['stream'] ?? '' );
		$dao    = new DataStream_DAO();

		WP_CLI::confirm(
			'' !== $stream
				? sprintf( 'Delete all synced records for stream "%s"?', $stream )
				: 'Delete ALL synced records?',
			$assoc_args
		);

		$deleted = '' !== $stream ? $dao->purge_by_stream_type( $stream ) : $dao->purge_all();
		DataStream_Provider::flush_all_caches();

		WP_CLI::success( sprintf( '%d records deleted.', (int) $deleted ) );
	}
}

WP_CLI::add_command( 'datastream', 'DataStream_CLI' );
