<?php
namespace SabaiApps\Directories\Component\Notification\SystemTool;

use SabaiApps\Directories\Component\Notification\Event\IEvent;
use SabaiApps\Directories\Component\System\Tool\AbstractTool;
use SabaiApps\Directories\Context;

class SendNotificationsSystemTool extends AbstractTool {

	protected function _systemToolInfo() {
		return array(
			'label'       => __( 'Send notifications', 'directories-pro' ),
			'description' => __( 'This tool will let you manually send notifications.', 'directories-pro' ),
			'weight'      => 100,
		);
	}

	public function systemToolSettingsForm( $step, array $values, array $parents = array(), ?Context $context = null ) {
		$notifications = $param_settings_form = array();
		foreach ( $this->_application->getModel( 'Notification', 'Notification' )->fetch( 0, 0, 'name', 'ASC' ) as $notification ) {
			if ( ( ! $event = $this->_application->Notification_Services_event( $notification->event, true ) )
				|| ! $event->notificationEventIsEnabled()
				|| ! $event->notificationEventInfo( 'testable' )
			) {
				continue;
			}

			$id                    = $notification->id;
			$notifications[ $id ]  = array(
				'name'   => $notification->data['label'],
				'weight' => $event->notificationEventInfo( 'weight' ),
				'label'  => $event->notificationEventInfo( 'label' ),
				'system' => $notification->system,
			);
			$notification_settings = isset( $notification->data['event'] ) ? (array) $notification->data['event'] : array();
			if ( $_param_settings_form = $event->notificationEventParamSettingsForm( $notification_settings, array( 'param_settings', $id ) ) ) {
				$param_settings_form[ $id ]            = $_param_settings_form;
				$param_settings_form[ $id ]['#states'] = array(
					'visible' => array(
						sprintf( '[name="%s"]', $this->_application->Form_Form_fieldName( array( $parents, 'notification' ) ) ) => array( 'value' => $id ),
					),
				);
			}
		}

		// Sort by weight and label
		uasort(
			$notifications,
			function ( $a, $b ) {
				if ( $a['weight'] < $b['weight'] ) {
					return -1;
				}
				if ( $a['weight'] === $b['weight'] ) {
					if ( 0 === $res = strcasecmp( $a['label'], $b['label'] ) ) {
						$res = $a['system'] > $b['system'] ? -1 : 1;
					}
					return $res;
				}
				return 1;
			}
		);
		foreach ( array_keys( $notifications ) as $id ) {
			$notifications[ $id ] = $notifications[ $id ]['name'];
		}

		return array(
			'#tree'          => true,
			'notification'   => array(
				'#title'      => __( 'Select notification', 'directories-pro' ),
				'#type'       => 'select',
				'#options'    => $notifications,
				'#horizontal' => true,
				'#required'   => true,
			),
			'param_settings' => $param_settings_form,
		);
	}

	public function systemToolInit( array $settings, array &$storage, array &$logs, ?Context $context = null ) {
		if ( ( ! $notification = $this->_application->getModel( 'Notification', 'Notification' )->fetchById( $settings['notification'] ) )
			|| empty( $notification->data['sender'] )
			|| ( ! $event = $this->_application->Notification_Services_event( $notification->event, true ) )
		) {
			return array();
		}

		$notification_settings = isset( $notification->data['event'] ) ? (array) $notification->data['event'] : array();
		$messages              = $this->_getMessages( $event, $notification_settings, empty( $settings['param_settings'][ $notification->id ] ) ? array() : $settings['param_settings'][ $notification->id ] );
		$ret                   = array();
		foreach ( array_keys( $notification->data['sender'] ) as $sender_name ) {
			if ( ! $sender = $this->_application->Notification_Services_sender( $sender_name, true ) ) {
				$this->_application->logError( 'Could not fetch notification sender: ' . $sender_name );
				continue;
			}
			if ( ! $count = $sender->notificationSenderCount( $notification_settings, $messages ) ) {
				continue;
			}

			$ret[ $sender_name ] = $count;
		}

		return $ret;
	}

	protected function _getMessages( IEvent $event, array $notificationSettings, array $settings ) {
		$params   = $event->notificationEventParams( $notificationSettings, $settings );
		$messages = $event->notificationEventMessages( $notificationSettings, $params );
		return $messages;
	}

	public function systemToolRunTask( $task, array $settings, $iteration, $total, array &$storage, array &$logs, ?Context $context = null ) {
		if ( ! $sender = $this->_application->Notification_Services_sender( $task, true ) ) {
			$logs['error'][] = 'Could not fetch notification sender: ' . $task;
		}

		if ( ( ! $notification = $this->_application->getModel( 'Notification', 'Notification' )->fetchById( $settings['notification'] ) )
			|| ( ! $event = $this->_application->Notification_Services_event( $notification->event, true ) )
		) {
			return;
		}

		$notification_settings = isset( $notification->data['event'] ) ? (array) $notification->data['event'] : array();
		$messages              = $this->_getMessages( $event, $notification_settings, empty( $settings['param_settings'][ $notification->id ] ) ? array() : $settings['param_settings'][ $notification->id ] );
		$sender->notificationSenderSend( $notification->data['sender'][ $task ], $messages );

		return 1;
	}
}
