<?php

namespace CelerSearch;

defined( 'ABSPATH' ) || exit;

use CelerSearch\Factories\ServiceFactory;
use CelerSearch\Interfaces\IRegistrable;
use CelerSearch\Repositories\ServiceRepository;
use CelerSearch\Utilities\Logger;

class Cron implements IRegistrable {

	/**
	 * Registers certain group of hooks (actions/filters)
	 * @return void
	 */
	public function register(): void {
		add_action( 'admin_init', [ static::class, 'schedule_service_check' ] );
		add_action( 'celersearch_service_check', [ $this, 'cron_service_check' ] );
	}

	public static function schedule_service_check(): void {
		if ( ! wp_next_scheduled( 'celersearch_service_check' ) ) {
			wp_schedule_event( time(), 'hourly', 'celersearch_service_check' );
		}
	}

	public function cron_service_check(): void {
		$repo = new ServiceRepository();

		try {
			$list = $repo->get();

			foreach ( $list as $service ) {
				try {
					$instance   = ServiceFactory::create( $service->getId() );
					$is_healthy = $instance->health_check();
				} catch ( \Exception $e ) {
					$is_healthy = false;
				}

				if ( $is_healthy ) {
					// Success - reset failure count
					$repo->update( $service->getId(), [
						'status'        => ServiceRepository::STATUS_CONNECTED,
						'failure_count' => 0,
						'checked_at'    => gmdate( 'Y-m-d H:i:s' ),
					] );
				} else {
					// Increment failure count
					$failure_count = $service->getFailureCount() + 1;
					$new_status    = $failure_count >= ServiceRepository::FAILURE_THRESHOLD
						? ServiceRepository::STATUS_FAILING
						: $service->getStatus();

					$repo->update( $service->getId(), [
						'status'        => $new_status,
						'failure_count' => $failure_count,
						'checked_at'    => gmdate( 'Y-m-d H:i:s' ),
					] );
				}
			}
		} catch ( \Exception $e ) {
			Logger::channel( Logger::CHANNEL_ERRORS )->error( 'Cron service check failed', [
				'exception' => $e->getMessage(),
			] );
		}
	}
}
