<?php
namespace SabaiApps\Directories\Component\System\Helper;

use SabaiApps\Directories\Application;

class ScheduledActionsHelper {

	public function help( Application $application, $useCache = true ) {
		if ( ! $useCache
			|| ( ! $actions = $application->getPlatform()->getCache( 'system_scheduled_actions' ) )
		) {
			$actions = array();
			foreach ( $application->InstalledComponentsByInterface( 'System\IScheduledActions' ) as $component_name ) {
				if ( ! $application->isComponentLoaded( $component_name ) ) {
					continue;
				}

				foreach ( $application->getComponent( $component_name )->systemScheduledActions() as $action_name => $action ) {
					$actions[ $action_name ] = array(
						'recurrence'  => $action['recurrence'] ?? 'daily',
						'title'       => $action['title'] ?? $action_name,
						'description' => $action['description'] ?? '',
						'args'        => $action['args'] ?? array(),
						'priority'    => $action['priority'] ?? 10,
					);
					if ( ! empty( $action['timestamp'] ) ) {
						$actions[ $action_name ]['timestamp'] = $action['timestamp'];
					}
					if ( isset( $action['enabled'] ) ) {
						$actions[ $action_name ]['enabled'] = $action['enabled'];
					}
					if ( ! empty( $action['immediate_actions'] ) ) {
						$actions[ $action_name ]['immediate_actions'] = $action['immediate_actions'];
					}
				}
				uasort(
					$actions,
					function ( $a, $b ) {
						return $a['priority'] <=> $b['priority'];
					}
				);
			}
			$application->getPlatform()->setCache( $actions, 'system_scheduled_actions' );
		}

		return $actions;
	}

	public function schedule( Application $application, $useCache = true ) {
		$actions         = $this->help( $application, $useCache );
		$actions_enabled = $application->getComponent( 'System' )->getConfig( 'scheduled_actions' );
		foreach ( $actions as $action_name => $action ) {
			if ( isset( $actions_enabled ) ) {
				// If action is not enabled, clear any existing scheduled actions
				if ( ! in_array( $action_name, $actions_enabled ) ) {
					$application->getPlatform()->getScheduler()->clearScheduledAction( $action_name, $action['args'] );
					continue;
				}
			} elseif ( isset( $action['enabled'] ) && ! $action['enabled'] ) {
					$application->getPlatform()->getScheduler()->clearScheduledAction( $action_name, $action['args'] );
					continue;
			}

			// If already scheduled, skip
			if ( $application->getPlatform()->getScheduler()->nextScheduledAction( $action_name, $action['args'] ) ) {
				continue;
			}

			$application->getPlatform()->getScheduler()->scheduleRecurringAction(
				$action['recurrence'],
				$action_name,
				$action['args'],
				$action['priority'],
				$action['timestamp'] ?? null
			);
		}
	}

	public function init( Application $application ) {
		$actions         = $this->help( $application );
		$actions_enabled = $application->getComponent( 'System' )->getConfig( 'scheduled_actions' );
		$application->getPlatform()->getScheduler()->initActions( empty( $actions_enabled ) ? $actions : array_intersect_key( $actions, array_flip( $actions_enabled ) ) );
	}

	public function recurrenceLabel( Application $application, $recurrence = null ) {
		switch ( $recurrence ) {
			case 'hourly':
				return __( 'Hourly', 'directories-pro' );
			case 'twicedaily':
				return __( 'Twice daily', 'directories-pro' );
			case 'daily':
				return __( 'Daily', 'directories-pro' );
			case 'weekly':
				return __( 'Weekly', 'directories-pro' );
			case 'monthly':
				return __( 'Monthly', 'directories-pro' );
			default:
				return array(
					'hourly'     => __( 'Hourly', 'directories-pro' ),
					'twicedaily' => __( 'Twice daily', 'directories-pro' ),
					'daily'      => __( 'Daily', 'directories-pro' ),
					'weekly'     => __( 'Weekly', 'directories-pro' ),
					'monthly'    => __( 'Monthly', 'directories-pro' ),
				);
		}
	}

	public function settingsForm( Application $application, ?array $settings = null, array $parents = array() ) {
		$form = array(
			'#type'                  => 'tableselect',
			'#title'                 => __( 'Scheduled Actions', 'directories-pro' ),
			'#description'           => sprintf(
				$application->H( __( 'Select the automated background tasks you want to enable. (System is currently using: %s)', 'directories-pro' ) ),
				'<strong>' . (string) $application->getPlatform()->getScheduler() . '</strong>'
			),
			'#description_no_escape' => true,
			'#multiple'              => true,
			'#js_select'             => false,
			'#header'                => array(
				'action'     => __( 'Action', 'directories-pro' ),
				'recurrence' => __( 'Recurrence', 'directories-pro' ),
				'next_run'   => __( 'Next Run', 'directories-pro' ),
			),
			'#row_attributes'        => array(
				'@all' => array(
					'action' => array(
						'style' => 'width:70%;',
					),
				),
			),
		);
		foreach ( $this->help( $application, false ) as $action_name => $action ) {
			$next_run                         = $application->getPlatform()->getScheduler()->nextScheduledAction( $action_name, $action['args'] );
			$form['#options'][ $action_name ] = array(
				'action'     => '<strong>' . $application->H( $action['title'] ) . '</strong><br>' . $application->H( $action['description'] ),
				'recurrence' => $this->recurrenceLabel( $application, $action['recurrence'] ),
				'next_run'   => $next_run ? $application->System_Date( $next_run ) : '',
			);
			if ( isset( $settings ) ) {
				if ( in_array( $action_name, $settings ) ) {
					$form['#default_value'][] = $action_name;
				}
			} elseif ( ! isset( $action['enabled'] ) || $action['enabled'] ) {
					$form['#default_value'][] = $action_name;
			}
		}

		return $form;
	}
}
