<?php

class Tbm_Tagmailer_Ajax {

	private $common;

	public function __construct() {
		$this->common = new Tbm_Tagmailer_Common();
	}

	/**
	 * Wrapper for tbm_newsletter_subscribe action (needed for parameter)
	 *
	 * @return array|null
	 */
	public function tbm_newsletter_subscribe_action() {
		return $this->tbm_newsletter_subscribe();
	}


	private function tbm_newsletter_subscribe_call( $tagmailer_data = array() ) {
		$data    = array();
		$profile = array();
		$out     = array();

		$gump = new GUMP();

		// Define data to handle
		$received_data = $tagmailer_data ?: $_POST;
		$received_data = $gump->sanitize( $received_data );

		try {
			GUMP::add_validator( "is_italian_phone", function ( $field, array $input, array $params, $value ) {
				if ( preg_match( '/[0-9\s+]{7,}/', $value ) ) {
					return true;
				} else {
					return false;
				}
			}, 'Field {field} must be at least 7 characters.' );
		} catch ( Exception $e ) {

		}

		$gump->validation_rules( array(
			// Base data
			'tbm_email'         => 'required|valid_email',
			'tbm_privacy'       => 'required|contains_list,true',

			// Container
			'tbm_container'     => 'integer',

			// Profiling
			'tbm_birth_date'    => 'integer|exact_len,4',
			'tbm_gender'        => 'exact_len,1|contains_list,m;f;x',
			'tbm_state'         => 'alpha',
			'tbm_qualification' => 'integer',
			'tbm_job'           => 'integer',
			'tbm_phone'         => 'is_italian_phone',

			// Logic
			'tbm_step'          => 'contains_list,1;2;full',

			// Source
			'tbm_amp'           => 'boolean',
			'tbm_modal'         => 'boolean'

		) );

		$gump->filter_rules( array(
			'tbm_email'         => 'trim',
			'tbm_birth_date'    => 'trim',
			'tbm_gender'        => 'trim',
			'tbm_state'         => 'trim',
			'tbm_qualification' => 'trim',
			'tbm_job'           => 'trim',
			'tbm_phone'         => 'trim',
			'tbm_tags'          => 'trim',
			'tbm_name'          => 'trim',
			'tbm_surname'       => 'trim|sanitize_string',
			'tbm_container'     => 'trim|sanitize_string'
		) );

		$validated_data = $gump->run( $received_data );

		if ( $validated_data === false ) {
			return array(
				'status' => 'gump_error',
				'error'  => $gump
			);
		}

		/**
		 * Container validation
		 */
		$container = isset( $validated_data['tbm_container'] ) && ! empty( $validated_data['tbm_container'] ) ? $validated_data['tbm_container'] : false;

		if ( ! $container ) {
			$container = $this->common->tbm_get_container_id();
		}

		if ( ! $container ) {
			return array(
				'status' => 'no_container'
			);
		}

		/**
		 * Profiles
		 */
		$tbm_birth_date    = ! empty( $validated_data['tbm_birth_date'] ) ? $validated_data['tbm_birth_date'] : '';
		$tbm_gender        = ! empty( $validated_data['tbm_gender'] ) ? $validated_data['tbm_gender'] : '';
		$tbm_state         = ! empty( $validated_data['tbm_state'] ) ? $validated_data['tbm_state'] : '';
		$tbm_job           = ! empty( $validated_data['tbm_job'] ) ? $validated_data['tbm_job'] : '';
		$tbm_qualification = ! empty( $validated_data['tbm_qualification'] ) ? $validated_data['tbm_qualification'] : '';
		$tbm_phone         = ! empty( $validated_data['tbm_phone'] ) ? $validated_data['tbm_phone'] : '';
		$tbm_name          = ! empty( $validated_data['tbm_name'] ) ? $validated_data['tbm_name'] : '';
		$tbm_surname       = ! empty( $validated_data['tbm_surname'] ) ? $validated_data['tbm_surname'] : '';

		$profile[] = array(
			'type'  => 'YearOfBirth',
			'value' => $tbm_birth_date
		);
		$profile[] = array(
			'type'  => 'Gender',
			'value' => $tbm_gender
		);
		$profile[] = array(
			'type'  => 'Province',
			'value' => $tbm_state
		);
		$profile[] = array(
			'type'  => 'Occupation',
			'value' => $tbm_job
		);
		$profile[] = array(
			'type'  => 'Degree',
			'value' => $tbm_qualification
		);
		$profile[] = array(
			'type'  => 'PhoneNumber',
			'value' => $tbm_phone
		);
		$profile[] = array(
			'type'  => 'Name',
			'value' => $tbm_name
		);
		$profile[] = array(
			'type'  => 'Surname',
			'value' => $tbm_surname
		);

		// Filter empty value in $profile
		$profile = array_filter( $profile, function ( $value ) {
			return ! empty( $value['value'] );
		} );

		$profile = array_values( $profile );

		/**
		 * Build request
		 */
		$data['email']           = $validated_data['tbm_email'];
		$data['privacyAccepted'] = (bool) $validated_data['tbm_privacy'];
		/**
		 * Acconsento al trattamento dei dati per attività di marketing.
		 */
		$data['marketingAccepted'] = ! empty( $validated_data['tbm_dem'] ) && $validated_data['tbm_dem'] === 'true';
		/**
		 * Acconsento al trattamento dei dati ai fini della comunicazione a terzi per loro attività di marketing
		 */
		$data['thirdPartyAccepted'] = ! empty( $validated_data['tbm_mktg'] ) && $validated_data['tbm_mktg'] === 'true';
		/**
		 * If user is not in legal age, drop DEM consent
		 */
		if ( isset( $validated_data['tbm_birth_date'] ) && $validated_data['tbm_birth_date'] + 18 >= (int) date( 'Y' ) ) {
			$data['thirdPartyAccepted'] = false;
			$data['marketingAccepted']  = false;
		}

		$data['ipAddress']   = $this->common->html_get_client_ip();
		$data['profilings']  = $profile;
		$data['containerId'] = ( int ) $container;

		/**
		 * Subscribe to newsletter
		 */
		$mailer_response = $this->tbm_tagmailer_api( 'subscribers', $data );

		/**
		 * Generate response
		 */

		// Error
		if ( isset( $mailer_response['error'] ) ) {
			if ( $mailer_response['error']['code'] ) {
				$out = 'code_' . $mailer_response['error']['code'];
			} else {
				$out = 'code_500';
			}
		}

		// Success
		if ( isset( $mailer_response['success'] ) ) {
			if ( isset( $mailer_response['success']['message'] ) && str_contains( $mailer_response['success']['message'], 'DoubleOptinRequested' ) ) {
				$out = 'code_200_optin';
			} else if ( isset( $mailer_response['success']['message'] ) && str_contains( $mailer_response['success']['message'], 'ContainerAlreadyExists' ) ) {
				$out = 'code_202';
			} else {
				$out = 'code_200';
			}
		}

		$returned_values = array(
			'status' => 'message',
			'code'   => $out
		);

		if ( defined( 'TBM_TAGMAILER_DEBUG' ) ) {
			$returned_values['debug'] = array(
				'response' => $mailer_response,
				'data'     => $data
			);
		}

		return $returned_values;

	}

	/**
	 * Chiamata ajax per l'iscrizione alla newsletter
	 *
	 * @param bool $display True to display response, false to return
	 * @param array $tagmailer_data The data to handle; default to $_POST server variable
	 *
	 * @return array|bool|void
	 * @throws Exception
	 */
	public function tbm_newsletter_subscribe( bool $display = true, array $tagmailer_data = array() ) {

		$result = $this->tbm_newsletter_subscribe_call( $tagmailer_data );

		// If gump error
		if ( $result['status'] === 'gump_error' ) {
			if ( $display ) {

				$this->common->tbm_gump_send_success_response( $result['error'], 'Abbiamo riscontrato un problema con i dati di iscrizione. Correggi e riprova.', 'validation_error' );
			} else {
				return false;
			}
		}

		// If no container
		if ( $result['status'] === 'no_container' ) {
			if ( $display ) {
				$this->common->tbm_gump_send_success_response( 'no containers', 'Abbiamo riscontrato un problema con i dati di iscrizione. Correggi e riprova.', 'validation_error' );
			} else {
				return false;
			}
		}

		// If message
		if ( $result['status'] === 'message' ) {
			$code = $result['code'] ?? '';
			if ( $display ) {
				$this->common->tbm_gump_send_success_response( $code, 'Risultato ' . $code, 'success' );
			} else {
				return $code;
			}
		}

		return true;

	}

	/**
	 * Posta la request d'iscrizione della newsletter per le nuove API
	 *
	 * @param string $method The method to call
	 * @param array $data The data to send in the body
	 */
	public function tbm_tagmailer_api( string $method, array $data = array() ): array {

		// Get Api Key
		if ( ! get_field( 'tbl_tagmailer_api_key', 'option' ) ) {
			return array( 'error' => array( 'code' => 500, 'message' => 'No API key defined' ) );
		}

		$api_key = get_field( 'tbl_tagmailer_api_key', 'option' );

		$response = wp_remote_post( TBM_TAGMAILER_V5_API . '/' . $method, array(
			'body'    => json_encode( $data ),
			'timeout' => 10,
			'headers' => array(
				"Content-Type"  => "application/json",
				"accept"        => "application/json",
				"cache-control" => "no-cache",
				"Api-Key"       => $api_key,
			),
		) );

		if ( is_wp_error( $response ) ) {
			return array(
				"error" => array(
					"code"    => wp_remote_retrieve_response_code( $response ),
					"message" => $response->get_error_message()
				)
			);
		}

		if ( 403 === wp_remote_retrieve_response_code( $response ) ) {
			return array(
				"error" => array(
					"code"    => wp_remote_retrieve_response_code( $response ),
					"message" => 'Invalid Api Key'
				)
			);
		}

		if ( 200 != wp_remote_retrieve_response_code( $response ) ) {
			return array(
				"error" => array(
					"code"    => wp_remote_retrieve_response_code( $response ),
					"message" => wp_remote_retrieve_body( $response )
				)
			);
		}


		// get response body
		$body = wp_remote_retrieve_body( $response );

		// Return success
		return array(
			"success" => array(
				"code"    => wp_remote_retrieve_response_code( $response ),
				"message" => $body
			)
		);
	}

}
