<?php
namespace EMS;

/**
 * Sendinblue service class.
 */
class Sendinblue {

	/**
     * API Key.
     *
     * @var string
     */
	private $api_key = '';

	/**
     * Key slug.
     *
     * @var string
     */
	private $key_slug = '';

	/**
     * Service slug.
     *
     * @var string
     */
	private $slug = 'sendinblue';

	/**
     * Service name.
     *
     * @var string
     */
	Private $name = 'Sendinblue';

	/**
     * Base key.
     *
     * @var string
     */
	private $base = 'ems_jetpack_crm';

	/**
	 * Class constructor.
	 */
	public function __construct() {
		$this->key_slug = $this->base . '_' . $this->slug;
		$this->api_key  = get_option( $this->key_slug . '_api_key' );

		$this->initialize_action_filter_hooks();

		if ( $this->is_valid_section() && ! empty( $_POST ) ) {
			if ( ! wp_verify_nonce( $_POST['_wpnonce'], $this->key_slug . '_form' ) ) exit;

			// Process form data.
			$this->form_control( $_POST );
		}
	}

	/**
	 * Check if we are on the correct page.
	 *
	 * @return bool
	 */
	public function is_valid_section() {
		if ( isset( $_GET['section'] ) ) {
			return $_GET['section'] === $this->slug;
		}

		return false;
	}

	/**
	 * Filter and Action hooks.
	 */
	public function initialize_action_filter_hooks() {
		add_filter( $this->base . '_services',               [ $this, 'register_service' ] );
		add_action( $this->base . '_content_' . $this->slug, [ $this, 'register_content' ] );
		add_action( 'admin_init',                            [ $this, 'run_error_message' ] );
		add_action( 'init',                                  [ $this, 'register_process' ] );
	}

	/**
	 * Register email service.
	 *
	 * @return array
	 */
	public function register_service( $services ) {
		$services[] = [ 'slug' => $this->slug, 'name' => $this->name ];

		return $services;
	}

	/**
	 * Register content.
	 */
	public function register_content() { ?>
		<h2><?= esc_html( $this->name ) ?></h2>

		<div class="content">
			<?php
				$crm_main_url    = get_option( $this->base . '_main_url' );
				$crm_main_key    = get_option( $this->base . '_main_key' );
				$crm_main_secret = get_option( $this->base . '_main_secret' );

				if ( ! $crm_main_url || ! $crm_main_key || ! $crm_main_secret ) {
					echo '<p class="ems-error">Please first setup CRM credentials in <a href="' . get_admin_url( null, '/admin.php?page=ems-jetpack-crm' ) . '">dashboard</a>.</p>';

					return;
				}
			?>

			<!-- Connection setup form -->
			<form class="ems-form" action="" method="POST">
				<div class="ems-input-group no-margin-bottom">
					<label for="ems-sendinblue-api-key">API Key</label>
					<input type="text" name="ems-sendinblue-api-key" id="ems-sendinblue-api-key" value="<?= esc_attr( $this->api_key ) ?>" required>
				</div>

				<?php wp_nonce_field( $this->key_slug . '_form' ); ?>

				<input type="submit" name="ems-form-sendinblue-connect" value="Save API Key">
			</form>

			<br>

			<div class="ems-info">
				<?php
					$process      = get_option( $this->key_slug . '_process' );
					$export_count = get_option( $this->key_slug . '_export_count', 0 );

					if ( $process ) {
						echo '<p class="in-progress">Still in progress, ' . absint( $export_count ) . ' contacts imported!';
					} else {
						echo '<p class="no-process">No process is running right now!</p>';
					}
				?>
			</div>

			<!-- Import contacts form -->
			<form class="ems-form" action="" method="POST">
				<p class="ems-what-to-import">Import: First Name, Last Name, Email and Mobile number.</p>

				<?php wp_nonce_field( $this->key_slug . '_form' ); ?>

				<input type="submit" name="ems-form-sendinblue-import" value="Import All Contacts">
			</form>

			<div class="ems-help">
				<h3>Help links:</h3>
				<p><?= esc_html( $this->name ) ?> <a href="https://app.sendinblue.com/contact/list" target="_blank">contacts</a></p>
				<p><?= esc_html( $this->name ) ?> v3 <a href="https://account.sendinblue.com/advanced/api" target="_blank">API key</a></p>
			</div>
		</div>
		<?php
	}

	/**
	 * Run error message based on error query value.
	 */
	public function run_error_message() {
		$valid_page = isset( $_GET['page'] ) ? 'ems-jetpack-crm' === $_GET['page'] : false;
		$error      = isset( $_GET['error'] ) ? sanitize_text_field( $_GET['error'] ) : '';

		$messages = [
			'no-api' => 'Please first setup ' . esc_html( $this->name ) . ' Api key.',
		];

		if ( ! $valid_page || ! array_key_exists( $error, $messages ) ) {
			return;
		}

		add_action( 'admin_notices', function() use ( $messages, $error ) { ?>
			<div class="notice notice-error is-dismissible">
				<p>Error: <?= esc_html( $messages[ $error ] ) ?></p>
			</div>
			<?php
		} );
	}

	/**
	 * Control form submission.
	 */
	private function form_control( $payload ) {
		// Connection setup form.
		if ( isset( $payload['ems-form-sendinblue-connect'] ) && isset( $payload['ems-sendinblue-api-key'] ) ) {
			$this->api_key = sanitize_text_field( $payload['ems-sendinblue-api-key'] );

			update_option( $this->key_slug . '_api_key', $this->api_key );
		}

		// Import contacts form.
		if ( isset( $payload['ems-form-sendinblue-import'] ) ) {
			if ( ! $this->api_key ) {
				wp_redirect( home_url( $_SERVER['REQUEST_URI'] ) . '&error=no-api' );
				exit;
			}

			update_option( $this->key_slug . '_process', true );
		}
	}

	/**
	 * Run the background process.
	 */
	public function register_process() {
		$action  = $this->key_slug . '_bg_action';
		$process = get_option( $this->key_slug . '_process' );

		if ( $process && ! as_has_scheduled_action( $action ) ) {
			$offset = get_option( $this->key_slug . '_offset', 0 );

			as_enqueue_async_action( $action, [ 'offset' => $offset ] );
		}

		add_action( $action, [ $this, 'export_contacts' ] );
	}

	/**
	 * Clean up to stop exporting.
	 * 
	 * @return string
	 */
	public function cleanup_process() {
		delete_option( $this->key_slug . '_process' );
		delete_option( $this->key_slug . '_offset' );
		delete_option( $this->key_slug . '_export_count' );

		return 'Process successfully stoped!';
	}

	/**
	 * Contacts export from service.
	 */
	public function export_contacts( $offset ) {
		if ( ! $this->api_key ) return;

		$limit        = 10;
		$offset       = absint( $offset );
		$config       = \SendinBlue\Client\Configuration::getDefaultConfiguration()->setApiKey( 'api-key', $this->api_key );
		$api_instance = new \SendinBlue\Client\Api\ContactsApi( new \GuzzleHttp\Client(), $config );

		try {
			$response = $api_instance->getContacts( $limit, $offset );
			$contacts = $response->getContacts();

			if ( empty( $contacts ) ) {
				return $this->cleanup_process();
			}

			// Update contacts query offset.
			update_option( $this->key_slug . '_offset', $limit + $offset );

			// Get and save the export count.
			$export_count = get_option( $this->key_slug . '_export_count', 0 );
			update_option(  $this->key_slug . '_export_count', $export_count + count( $contacts ) );

			$this->import_contacts( $contacts );

		} catch ( Exception $e ) {
			echo 'Exception when calling ContactsApi->getContacts: ', esc_html( $e->getMessage() ), PHP_EOL;
		}
	}

	/**
	 * Contacts import to CRM from service.
	 */
	public function import_contacts( $contacts ) {
		$crm_main_url    = get_option( $this->base . '_main_url' );
		$crm_main_key    = get_option( $this->base . '_main_key' );
		$crm_main_secret = get_option( $this->base . '_main_secret' );

		if ( ! $crm_main_url || ! $crm_main_key || ! $crm_main_secret ) {
			return;
		}

		$api_contact_url = $crm_main_url . 'create_customer?api_key=' . $crm_main_key . '&api_secret=' . $crm_main_secret;

		foreach ( $contacts as $contact ) {
			$attributes = $contact['attributes'];
			
			$body = [
				'json' => [
					'email' => $contact['email'],

					'fname'  => empty( $attributes->FIRSTNAME ) ? '' : $attributes->FIRSTNAME,
					'lname'  => empty( $attributes->LASTNAME )  ? '' : $attributes->LASTNAME,
					'mobtel' => empty( $attributes->SMS )       ? '' : $attributes->SMS,
				]
			];

			(new \GuzzleHttp\Client())->request( 'POST', $api_contact_url, $body );
		}
	}

}

// Init service.
new Sendinblue();
