<?php

class HappyForms_Client_Info {

	private static $instance;
	private static $hooked = false;

	public static function instance() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();
		}

		self::$instance->hook();

		return self::$instance;
	}

	public function hook() {
		if ( self::$hooked ) {
			return;
		}

		self::$hooked = true;

		add_action( 'happyforms_form_open', array( $this, 'render_field' ) );
		add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ) );
		add_action( 'happyforms_response_created', array( $this, 'append_response_info' ), 10, 2 );
		add_action( 'happyforms_draft_created', array( $this, 'append_response_info' ), 10, 2 );
		add_action( 'happyforms_response_metabox_details', array( $this, 'metabox_details' ) );
	}

	public function render_field() {
		?>
		<div data-happyforms-type="client_info">
			<?php if ( $this->should_save_meta_data() ) : ?>
			<input type="hidden" name="client_info[date]" />
			<input type="hidden" name="client_info[timezone]" />
			<input type="hidden" name="client_info[platform]" />
			<input type="hidden" name="client_info[language]" />
			<?php endif; ?>
			<input type="hidden" name="client_info[referer]" />
		</div>
		<?php
	}

	public function script_dependencies( $deps ) {
		wp_register_script(
			'happyforms-client-info',
			happyforms_get_plugin_url() . 'inc/assets/js/frontend/client-info.js',
			array(), HAPPYFORMS_UPGRADE_VERSION, true
		);

		$deps[] = 'happyforms-client-info';

		return $deps;
	}

	public function get_defaults() {
		$ip = $this->get_ip();
		$defaults = array(
			'date' => '',
			'timezone' => '',
			'platform' => '',
			'language' => '',
			'ip' => $ip,
			'referer' => '',
		);

		return $defaults;
	}

	public function get_ip() {
		if ( $this->should_save_meta_data() ) {
			$keys = array( 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR' );

			foreach( $keys as $key ) {
				if ( isset( $_SERVER[$key] ) && ! empty( $_SERVER[$key] ) ) {
					return $_SERVER[$key];
				}
			}
		}

		return '';
	}

	public function should_save_meta_data( $form = array() ) {
		$form = empty( $form ) ? array( 'ID' => 0 ) : $form;
		$save_meta_data = false;

		if ( ! metadata_exists( 'post', $form['ID'], '_happyforms_save_meta_data' ) ) {
			$save_meta_data = true;
		}

		if ( 1 == happyforms_get_meta( $form['ID'], 'save_meta_data', true ) ) {
			$save_meta_data = true;
		}

		$save_meta_data = apply_filters( 'happyforms_save_user_data', $save_meta_data );

		return $save_meta_data;
	}

	public function append_response_info( $response_id, $form ) {
		if ( isset( $_REQUEST['client_info'] ) ) {
			$client_info = wp_parse_args( $_REQUEST['client_info'], $this->get_defaults() );
			
			foreach( $client_info as $field => $value ) {
				$client_info[$field] = (
					( 'referer' !== $field ) ? 
					sanitize_text_field( $value ) :
					esc_url_raw( $value )
				);
			}

			foreach( $client_info as $key => $info ) {
				switch( $key ) {
					case 'language':
						$info = explode( '-', $info );
						$info = $info[0];
					default:
						happyforms_update_meta( $response_id, "client_{$key}", $info );
						break;
				}
			}
		}
	}

	public function metabox_details( $response_id ) {
		$defaults = $this->get_defaults();

		foreach( $defaults as $key => $default ) {
			$info = happyforms_get_meta( $response_id, "client_{$key}", true );
			$method = "metabox_details_{$key}";

			if ( ! $info || ! method_exists( $this, $method ) ) {
				continue;
			}

			call_user_func( array( $this, $method ), $info );
		}
	}

	public function metabox_details_date( $info ) {
		$date = DateTime::createFromFormat( 'Y-m-d H:i:s', $info );

		if ( ! $date ) {
			return;
		} ?>
		<div class="misc-pub-section curtime misc-pub-curtime">
			<span id="timestamp">
				<?php _e( 'Local time', 'happyforms' ); ?>: <b><?php echo $date->format( 'M j, Y' ); ?> <?php _e( 'at', 'happyforms' ); ?> <?php echo $date->format( 'H:i' ); ?></b>
			</span>
		</div>
		<?php
	}

	public function metabox_details_platform( $info ) {
		if ( empty( $info ) ) {
			return;
		} ?>
		<div class="misc-pub-section">
			<span>
				<i class="dashicons dashicons-tablet"></i>
				<?php _e( 'Platform used', 'happyforms' ); ?>: <b><?php echo ucfirst( $info ); ?></b>
			</span>
		</div>
		<?php
	}

	public function metabox_details_ip( $info ) {
		if ( empty( $info ) ) {
			return;
		} ?>
		<div class="misc-pub-section">
			<span>
				<i class="dashicons dashicons-admin-home"></i>
				<?php _e( 'IP', 'happyforms' ); ?>: <b><?php echo $info; ?></b>
			</span>
		</div>
		<?php
	}

	public function get_activity_info( $activity ) {
		$defaults = $this->get_defaults();
		$info = array();

		foreach( $defaults as $key => $value ) {
			$value = happyforms_get_meta( $activity['ID'], "client_{$key}", true );
			$info[$key] = $value ? $value : '';
		}

		return $info;
	}

	public function get_client_info_for_email( $response ) {
		if ( empty( $response ) ) {
			return;
		}

		$client_ip = happyforms_get_meta( $response['ID'], 'client_ip', true );
		$client_date = happyforms_get_meta( $response['ID'], 'client_date', true );
		$client_timezone = happyforms_get_meta( $response['ID'], 'client_timezone', true );

		$datetime = DateTime::createFromFormat( 'Y-m-d H:i:s', $client_date );
		$date_formatted = $datetime->format( get_option( 'date_format' ) );
		$time_formatted = $datetime->format( get_option( 'time_format' ) );
		$timezone = "UTC{$client_timezone}";
		$date_string = "{$date_formatted} {$time_formatted} {$timezone}";

		$client_data = array(
			'ip' => $client_ip,
			'date' => $client_date,
			'timezone' => $client_timezone,
		);

		$value = sprintf(
			'&#9432; %s | %s',
			$client_ip,
			$date_string
		);

		return apply_filters( 'happyforms_user_meta_email_data', $value, $client_data );
	}

}

if ( ! function_exists( 'happyforms_get_client_info' ) ):

function happyforms_get_client_info() {
	return HappyForms_Client_Info::instance();
}

endif;

happyforms_get_client_info();
