<?php
/**
 * Contacter
 * Voice feedback form for your website for saving and transcribing user voice messages to text.
 * Exclusively on https://1.envato.market/contacter
 *
 * @encoding        UTF-8
 * @version         1.7.8
 * @copyright       (C) 2018 - 2023 Merkulove ( https://merkulov.design/ ). All rights reserved.
 * @license         Envato License https://1.envato.market/KYbje
 * @contributors    Dmitry Merkulov (dmitry@merkulov.design)
 * @support         help@merkulov.design
 **/

namespace Merkulove\Contacter;

use Merkulove\Contacter\Unity\Plugin;
use Merkulove\Contacter\Unity\Settings;

/** Exit if accessed directly. */
if ( ! defined( 'ABSPATH' ) ) {
	header( 'Status: 403 Forbidden' );
	header( 'HTTP/1.1 403 Forbidden' );
	exit;
}

/**
 * SINGLETON: Class used to add contacter_form post type.
 *
 * @since 1.0.0
 *
 **/
final class CROptionsMetaBox {

	/**
	 * The one true CROptionsMetaBox.
	 *
	 * @var CROptionsMetaBox
	 * @since 1.0.0
	 **/
	private static $instance;

	/**
	 * Sets up a new instance.
	 *
	 * @since 1.0.0
	 * @access public
	 **/
	private function __construct() {

	}

	/**
	 * Render "Options" metabox with all fields.
	 *
	 * @param $contacter_record - Post Object.
	 *
	 * @since 1.0.0
	 **/
	public function render_metabox( $contacter_record ) {

		/** Render Nonce field to validate on save. */
		$this->render_nonce();

		?>
		<div class="mdp-options-box">
			<table class="form-table">
				<tbody>
				<?php

				/** Render Player field. */
				$this->render_player( $contacter_record );

				/** Render Transcription text field. */
				$speech_recognition = 'on' === Settings::get_instance()->options['speech_recognition'];
				$dnd_api_key = Settings::get_instance()->options['dnd-api-key'];
				if ( $speech_recognition && $dnd_api_key ) {
					$this->render_transcription( $contacter_record );
				}

				/** Render Additional fields field. */
				$this->additional_fields( $contacter_record );

                /** Render user location info */
                if ( get_post_meta( $contacter_record->ID, 'contacter_ip', true ) ) {
	                $this->render_user_info( $contacter_record );
                }

                /** Show record ID */
                if ( Settings::get_instance()->options[ 'show_record_id' ] === 'on' ) {
	                $this->render_record_id();
                }

				?>
				</tbody>
			</table>
		</div>
		<?php
	}

	/**
     * Render user ip and country
	 * @param $contacter_record
	 *
	 * @return void
	 */
    private function render_user_info( $contacter_record ) {

        ?>
        <tr>
            <th scope="row">
                <label><?php esc_html_e( 'Location', 'contacter' ); ?>:</label>
            </th>
            <td>
                <?php
                echo wp_sprintf(
	                '<div class="mdp-user-info">
                                <img src="%2$s" alt="%3$s, %4$s">
                                <span><b>%3$s, %4$s</b> (%1$s)</span>
                            </div>',
	                get_post_meta( $contacter_record->ID, 'contacter_ip', true ),
	                Plugin::get_url() . '/images/flags/'. strtolower( get_post_meta( $contacter_record->ID, 'contacter_country', true ) ) . '.svg',
	                apply_filters( 'contacter_country', get_post_meta( $contacter_record->ID, 'contacter_country_name', true ) ),
	                get_post_meta( $contacter_record->ID, 'contacter_city', true )
                );
                ?>
            </td>
        </tr>
        <?php

    }

	/**
     * Render record ID
	 * @return void
	 */
    private function render_record_id() {

	    ?>
        <tr>
            <th scope="row">
                <label><?php esc_html_e( 'Record ID', 'contacter' ); ?>:</label>
            </th>
            <td>
			    <?php
			    echo wp_sprintf(
				    '<div class="mdp-record-id">%s</div>',
				    get_the_ID()
			    );
			    ?>
            </td>
        </tr>
        <?php

    }

	/**
	 * Save all metabox with all fields.
	 *
	 * @param $post_id - Post Object.
	 * @since 1.0.0
	 **/
	public function save_metabox( $post_id ) {

		/** Options fields keys. */
		$k = [
			'mdp_transcription_txt', // Transcription.
			'mdp_notes_txt', // Notes Text.
        ];

		/** Save each field. */
		foreach ( $k as $field ) {
			$value = ( isset( $_POST[$field] ) ? wp_kses_post( $_POST[$field] ) : '' );
			update_post_meta( $post_id, $field, $value );
        }

    }

	/**
	 * Render Player field.
	 *
	 * @param $contacter_record - Current Contacter Record Object.
	 *
	 * @since 1.0.0
	 **/
	public function render_player( $contacter_record ) {

	    /** Get Audio path value from meta if it's exist. */
		$audio_path = get_post_meta( $contacter_record->ID, 'mdp_contacter_audio', true );
		if ( empty( $audio_path ) ) { return; }

		?>
        <tr>
            <th scope="row">
                <label><?php esc_html_e( 'Voice Message', 'contacter' ); ?>:</label>
            </th>
            <td>
                <div>
                    <?php $audio_url = $this->abs_path_to_url( $audio_path ); ?>
		            <?php echo do_shortcode( '[audio src="' . $audio_url . '"]' ); ?>
                    <div class="mdp-contacter-audio-info">
                        <span class="dashicons dashicons-download" title="<?php esc_html_e( 'Download audio', 'contacter' ); ?>"></span>
                        <a href="<?php echo esc_url( $audio_url ); ?>" download=""><?php esc_html_e( 'Download audio', 'contacter' ); ?></a>
                    </div>
                </div>
            </td>
        </tr>
		<?php

    }

	/**
	 * Return wav file duration 00:00.
	 *
	 * @param string $file - Full Path to file.
	 * @since 1.0.0
	 * @return string|null
	 **/
	public function get_wav_duration( $file ) {

		$fp = fopen( $file, 'r' );

		if ( fread( $fp, 4 ) == "RIFF" ) {

			fseek( $fp, 20 );
			$raw_header = fread( $fp, 16 );

			/** @noinspection SpellCheckingInspection */
			$header = unpack( 'vtype/vchannels/Vsamplerate/Vbytespersec/valignment/vbits', $raw_header );
			$pos = ftell( $fp );

			while ( fread( $fp, 4 ) != "data" && ! feof( $fp ) ) {
				$pos ++;
				fseek( $fp, $pos );
			}

			$raw_header = fread( $fp, 4 );

			/** @noinspection SpellCheckingInspection */
			$data = unpack( 'Vdatasize', $raw_header );

			/** @noinspection SpellCheckingInspection */
			$sec = $data[ 'datasize' ] / $header[ 'bytespersec' ];

			$minutes = (int) ( ( $sec / 60 ) % 60 );
			$seconds = (int) ( $sec % 60 );

			return str_pad( $minutes, 2, "0", STR_PAD_LEFT ) . ":" . str_pad( $seconds, 2, "0", STR_PAD_LEFT );

		}

		return null;

	}

	/**
	 * Convert the file path to URL of the same file.
	 *
	 * @param string $path - Full Path to file.
	 * @since 1.0.0
	 * @return string
	 **/
	public function abs_path_to_url( $path = '' ) {

		$url = str_replace(
			wp_normalize_path( untrailingslashit( ABSPATH ) ),
			site_url(),
			wp_normalize_path( $path )
		);

		return esc_url_raw( $url );
	}

	/**
	 * Render Transcription text field.
	 *
	 * @param $contacter_record - Current Contacter Form Object.
	 *
	 * @since 1.0.0
	 **/
	private function render_transcription( $contacter_record ) {

		/** Get Transcription Text field value from meta if it's already been entered. */
		$transcription = get_post_meta( $contacter_record->ID, 'mdp_transcription_txt', true );

		/** Default value. */
		if ( empty( $transcription ) ) { $transcription = ''; }
		?>
		<tr>
			<th scope="row">
				<label for="mdpbeforetxt"><?php esc_html_e( 'Transcription', 'contacter' ); ?>:</label>
			</th>
			<td>
                <button class="mdp-generate-transcription-btn"><?php esc_html_e( 'Generate Transcription', 'contacter' ); ?></button>
				<?php wp_editor( $transcription, 'mdptranscriptiontxt', [
				        'media_buttons' => 0,
				        'teeny' => 1,
				        'textarea_rows' => 5,
                        'textarea_name' => 'mdp_transcription_txt'
                ] ); ?>
				<p class="description"><?php esc_html_e( 'Press "Generate Transcription" button to generate or refresh transcription.', 'contacter' ); ?></p>
			</td>
		</tr>
		<?php
	}

	/**
	 * Render Additional fields value.
	 *
	 * @param $contacter_record - Current Contacter Form Object.
	 *
	 * @since 1.0.0
	 **/
	private function additional_fields( $contacter_record ) {

		/** Get Additional fields switcher value from meta if it's already been entered. */
		$mdp_additional_fields = get_post_meta( $contacter_record->ID, 'mdp_additional_fields', true );

		/** Get Attachments data array */
        $mdp_attachments = get_post_meta( $contacter_record->ID, 'mdp_attachments', true );
		$mdp_attachments = is_array( $mdp_attachments ) ? $mdp_attachments : [];

		/** Default value. Additional Fields switcher. */
		if ( '' === $mdp_additional_fields ) {
			$mdp_additional_fields = '';
		}

		$fields = json_decode( $mdp_additional_fields, true );
        if ( ! is_array( $fields ) ) { return; }
		if ( count( $fields ) === 0 && count( $mdp_attachments ) === 0 ) { return; }
		?>
        <tr>
            <th scope="row">
                <label><?php esc_html_e( 'Additional fields', 'contacter' ); ?>:</label>
            </th>
            <td>
                <div class="mdp-additional-fields-box">
                    <table>
                    <?php

                    // Render additional fields
                    foreach ( $fields as $key => $field  ) {
	                    ?>
                        <tr class="<?php esc_attr_e( $key ); ?>">
                            <td><strong><?php esc_html_e( $field['label'] ); ?>:</strong></td>
                            <td>
                                <?php if ( is_array( $field['value'] ) ) : ?>
                                    <ul>
                                    <?php foreach ( $field['value'] as $v ) : ?>
                                        <li><span><?php esc_html_e( $v ); ?></span></li>
                                    <?php endforeach; ?>
                                    </ul>
                                <?php else: ?>
                                    <span><?php esc_html_e( $field['value'] ); ?></span>
                                <?php endif; ?>
                            </td>
                        </tr>
                        <?php
                    }

                    // Render attachments
                    foreach ( $mdp_attachments as $key => $file_path ) {

                        $file_url = $this->abs_path_to_url( $file_path );
                        $file_ext = mime_content_type( $file_path );
                        $file_size = filesize( $file_path ) / 1024; // in kilobytes

                        $label = $this->get_attachment_label( get_post_meta( $contacter_record->ID, 'mdp_cform_id', true ), $key );
                        $size = esc_attr__( number_format( $file_size, 2, '.', '') ) . ' kB';

                        ?>
                        <tr class="<?php esc_attr_e( $key ); ?>">
                            <td>
                                <strong><?php esc_html_e( $label, 'contacter' ); ?>:</strong>
                            </td>
                            <td>
                                <a href="<?php echo esc_url( $file_url ); ?>" target="_blank"><?php esc_html_e( 'Attachment file', 'contacter' ); ?></a>
                                <span>( <?php esc_attr_e( $size ); ?>, <?php esc_attr_e( $file_ext );?> )</span>
                            </td>
                        </tr>
                        <?php
                    }

                    ?>
                    </table>
                </div>
            </td>
        </tr>
		<?php
	}

    /**
     * Get lable for attachment field
     *
     * @param string $cform_id - Contact form id
     * @param string $field_key - Attachment field key
     *
     * @return mixed|string
     */
	private function get_attachment_label( $cform_id, $field_key ) {

        $addional_fields = json_decode( get_post_meta( $cform_id, 'mdp_additional_fields_fb', true ), true );
        $label = esc_html__( 'Attachment', 'contacter' );

        foreach ( $addional_fields as $key => $field ) {

            if ( $field[ 'type' ] === 'file' && $field[ 'name' ] === $field_key ) {

                $label = $field[ 'label' ];
                break;

            }

        }

        return $label;

    }

	/**
	 * Render Nonce field to validate form request came from current site.
	 *
	 * @since 1.0.0
	 **/
	private function render_nonce() {

		wp_nonce_field( Plugin::get_basename(), 'options_metabox_fields_nonce' );

	}

	/**
	 * Main CROptionsMetaBox Instance.
	 *
	 * Insures that only one instance of CROptionsMetaBox exists in memory at any one time.
	 *
	 * @static
	 * @return CROptionsMetaBox
	 * @since 1.0.0
	 **/
	public static function get_instance() {
		if ( ! isset( self::$instance ) && ! ( self::$instance instanceof CROptionsMetaBox ) ) {
			self::$instance = new CROptionsMetaBox;
		}

		return self::$instance;
	}

} // End Class CROptionsMetaBox.
