<?php
namespace SabaiApps\Directories\Component\Faker\Generator;

use SabaiApps\Directories\Component\Field\IField;
use SabaiApps\Directories\Exception;
use SabaiApps\Directories\Component\Entity\Type\IEntity;

class RandomUserPhotoGenerator extends AbstractGenerator {

	protected function _fakerGeneratorInfo() {
		return array(
			'label'            => __( 'User Face Photo Generator', 'directories-pro' ),
			'description'      => __( 'Generate user face photos using Random User Generator API (https://randomuser.me/).', 'directories-pro' ),
			'field_types'      => array( 'wp_image' ),
			'add_probability'  => true,
			'default_settings' => array(
				'max' => 5,
			),
		);
	}

	public function fakerGeneratorSettingsForm( IField $field, array $settings, $mode, array $parents = array() ) {
		$form = array(
			'max' => $this->_getMaxNumItemsSettingForm( $field, $settings['max'] ),
		);
		if ( $mode !== 'new' ) {
			$form['preserve_existing'] = array(
				'#type'          => 'checkbox',
				'#title'         => __( 'Preserve existing', 'directories-pro' ),
				'#description'   => __( 'If checked, existing photos will be preserved and new photos will be added to them.', 'directories-pro' ),
				'#default_value' => true,
			);
		}
		return $form;
	}

	public function fakerGeneratorGenerate( IField $field, array $settings, array &$formStorage, ?IEntity $entity = null ) {
		if ( ! $user_photos = $this->_application->getPlatform()->getCache( 'faker_random_user_photos' ) ) {
			$url = 'https://randomuser.me/api?results=30';
			try {
				$result = $this->_application->getPlatform()->remoteGet(
					$url,
					array(
						'headers' => array(
							'Accept'        => 'application/json',
							'Cache-Control' => 'no-cache',
						),
					)
				);
				if ( ! $result = json_decode( $result, true ) ) {
					throw new Exception\RuntimeException( 'Failed decoding JSON returned from randomuser.me.' );
				}
				if ( empty( $result['results'] ) ) {
					throw new Exception\RuntimeException( 'No user photos found in the response from randomuser.me.' );
				}
				$user_photos = $result['results'];
			} catch ( \Exception $e ) {
				$this->_application->logError( $e->getMessage() );
				return false;
			}
			$this->_application->getPlatform()->setCache( $user_photos, 'faker_random_user_photos', 86400 );
		}

		if ( empty( $user_photos ) ) {
			return false;
		}

		if ( ! isset( $formStorage['faker_random_user_photos'] ) ) {
			$formStorage['faker_random_user_photos'] = array();
		}

		$ret = array();
		$num = $this->_getMaxNumItems( $field, $settings['max'] );
		$i   = 0;
		do {
			++$i;
			$index = mt_rand( 0, count( $user_photos ) - 1 );
			$photo = $user_photos[ $index ];
			unset( $user_photos[ $index ] );
			$user_photos = array_values( $user_photos );

			$id = $photo['id']['value'];
			if ( isset( $ret[ $id ] ) ) {
				continue;
			}

			if ( ! isset( $formStorage['faker_random_user_photos'][ $id ] ) ) {
				$url = $photo['picture']['large'];
				try {
					$file_path = $this->_application->getPlatform()->downloadUrl( $url );
				} catch ( \Exception $e ) {
					$this->_application->logError( $e );
					continue;
				}

				try {
					$file = $this->_application->getPlatform()->uploadFile(
						$file_path,
						'random-user-photo-' . $id . '.jpeg',
						$photo['name']['first'] . ' ' . $photo['name']['last'],
					);
				} catch ( \Exception $e ) {
					@unlink( $file_path );
					$this->_application->logError( $e );
					continue;
				}

				$formStorage['faker_random_user_photos'][ $id ] = $file;
			}

			$ret[ $id ] = $formStorage['faker_random_user_photos'][ $id ];

		} while ( count( $ret ) < $num && $i < $num + 5 && count( $user_photos ) > 0 );

		$this->_application->getPlatform()->setCache( $user_photos, 'faker_random_user_photos', 86400 * 7 );

		$ret = array_values( $ret );

		if ( isset( $entity )
			&& ! empty( $settings['preserve_existing'] )
			&& ( $current_photos = $entity->getFieldValue( $field->getFieldName() ) )
		) {
			foreach ( $current_photos as $photo ) {
				$ret[] = $photo;
			}
		}

		return $ret;
	}
}
