<?php
/**
 * Theme helper class
 *
 * @link https://www.fooevents.com
 * @package woocommerce-events
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Theme helper class
 */
class FooEvents_Theme_Helper {

	/**
	 * Configuration object
	 *
	 * @var object $config contains paths and other configurations
	 */
	public $config;

	/**
	 * Mail helper object
	 *
	 * @var object $mail_helper Mail helper object
	 */
	public $mail_helper;

	/**
	 * Barcode helper object
	 *
	 * @var object $barcode_helper Barcode helper object
	 */
	private $barcode_helper;

	/**
	 * On class load
	 *
	 * @param array $config configuration values.
	 */
	public function __construct( $config ) {

		$this->config = $config;
		add_action( 'admin_menu', array( $this, 'add_menu_item' ) );
		add_action( 'admin_menu', array( $this, 'add_fooevents_themes_count_badge' ), 999 );

		// add_action( 'admin_init', array( $this, 'register_scripts' ) );

		// Mail Helper.
		require_once $this->config->class_path . 'class-fooevents-mail-helper.php';
		$this->mail_helper = new FooEvents_Mail_Helper( $this->config );
	}

	/**
	 * Add admin ticket themes menu item
	 */
	public function add_menu_item() {

		add_submenu_page( 'fooevents', __( 'Ticket Themes', 'woocommerce-events' ), __( 'Ticket Themes', 'woocommerce-events' ), 'update_plugins', 'fooevents-ticket-themes', array( $this, 'display_ticket_themes_page' ) );
	}

	/**
	 * Register ticket theme scripts.
	 */
	public function register_scripts() {
	}

	/**
	 * Display ticket themes page
	 */
	public function display_ticket_themes_page() {

		if ( ! empty( $_POST['fooevents-theme-viewer-preview-input'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification

			$this->send_preview( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification

		}

		if ( ! empty( $_FILES['fooevents-theme-viewer-upload-file'] ) ) {

			$this->upload_themes( $_FILES );

		}

		$themes = $this->get_ticket_themes();

		$user       = wp_get_current_user();
		$user_email = $user->user_email;

		include $this->config->template_path . 'ticket-themes-viewer.php';
	}

	/**
	 * Connect to update service to get latest FooEvents theme version numbers.
	 */
	public function get_latest_fooevents_themes() {

		$url       = 'https://updates.fooevents.com/themes.php';
		$cache_key = 'fooevents_themes_latest_versions';

		$themes = get_transient( $cache_key );

		if ( false !== $themes ) {

			return $themes;

		}

		$response = wp_remote_get( $url, array( 'timeout' => 15 ) );

		if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {

			$error_msg = 'API currently unavailable.';

			set_transient( $cache_key, $error_msg, 5 * MINUTE_IN_SECONDS );
			return false;

		}

		$body   = wp_remote_retrieve_body( $response );
		$result = json_decode( $body, true );

		if ( ! empty( $result ) && is_array( $result ) ) {

			set_transient( $cache_key, $result, 24 * HOUR_IN_SECONDS );
			return $result;

		} else {

			$error_msg = 'Invalid data format received.';
			set_transient( $cache_key, $error_msg, 5 * MINUTE_IN_SECONDS );
			return false;

		}
	}

	/**
	 * Upload new ticket theme
	 *
	 * @param array $form form.
	 */
	public function upload_themes( $form ) {

		if ( ! wp_verify_nonce( $_POST['_wpnonce'], 'fooevents_upload_theme' ) ) {

			wp_die( __( 'NONCE authentication failed. Please try again.', 'woocommerce-events' ) );

		}

		if ( ! empty( $_FILES['fooevents-theme-viewer-upload-file']['name'] ) ) {

			$type = '';
			if ( isset( $_FILES['fooevents-theme-viewer-upload-file']['type'] ) ) {

				$type = sanitize_text_field( wp_unslash( $_FILES['fooevents-theme-viewer-upload-file']['type'] ) );

			}

			$accepted            = false;
			$accepted_file_types = array( 'application/zip', 'application/x-zip-compressed', 'multipart/x-zip', 'application/x-compressed' );
			foreach ( $accepted_file_types as $file_type ) {

				if ( $file_type === $type ) {

					$accepted = true;
					break;

				}
			}

			if ( $accepted ) {

				$filename_parts = explode( '.', sanitize_text_field( wp_unslash( $_FILES['fooevents-theme-viewer-upload-file']['name'] ) ) );
				$folder_name    = preg_replace( '/\([^)]+\)/', '', $filename_parts[0] );
				$path           = $this->config->theme_packs_path . sanitize_text_field( wp_unslash( $_FILES['fooevents-theme-viewer-upload-file']['name'] ) );
				$target_dir     = $this->config->theme_packs_path . $folder_name;

				$overwrite_confirmed = isset( $_POST['fooevents-overwrite-confirm'] ) && $_POST['fooevents-overwrite-confirm'] === '1';

				if ( file_exists( $target_dir ) && ! $overwrite_confirmed ) {

					$this->output_notices( array( __( 'Theme already exists. Please check the overwrite confirmation box to replace it.', 'woocommerce-events' ) ) );

					return;

				}

				if ( move_uploaded_file( $_FILES['fooevents-theme-viewer-upload-file']['tmp_name'], $path ) ) {

					if ( file_exists( $path ) ) {

						$zip    = new ZipArchive();
						$status = $zip->open( $path );

						if ( true === $status ) {

							$zip->extractTo( $this->config->theme_packs_path );
							$zip->close();

							$theme_path = $target_dir;

							if ( file_exists( $theme_path . '/header.php' ) && file_exists( $theme_path . '/footer.php' ) && file_exists( $theme_path . '/ticket.php' ) ) {
								$this->output_notices( array( __( 'Theme has been updated/uploaded.', 'woocommerce-events' ) ) );
							} else {
								$this->output_notices( array( __( 'File does not contain valid theme files.', 'woocommerce-events' ) ) );
							}

							unlink( $path );
						}
					}
				}

				delete_transient( 'fooevents_themes_update_count' );

			} else {

				$this->output_notices( array( __( 'Please upload valid .zip file', 'woocommerce-events' ) ) );

			}
		}
	}

	/**
	 * Send ticket theme preview
	 *
	 * @param array $form form.
	 */
	public function send_preview( $form ) {

		if ( ! empty( $form['fooevents-theme-viewer-preview-input'] ) && ! empty( $form['fooevents-theme-viewer-preview-path'] ) ) {

			$theme      = $form['fooevents-theme-viewer-preview-path'];
			$send_to    = $form['fooevents-theme-viewer-preview-input'];
			$theme_name = $form['fooevents-theme-viewer-preview-theme-name'];

			$ticket = $this->get_demo_ticket();

			$header = $this->mail_helper->parse_email_template( $theme . '/header.php', $ticket, array() );
			$footer = $this->mail_helper->parse_email_template( $theme . '/footer.php', $ticket, array() );
			$body   = $this->mail_helper->parse_ticket_template( $theme . '/ticket.php', $ticket, array(), true );

			$subject = $theme_name . ': Preview Ticket';

			$mail_status = $this->mail_helper->send_ticket( $send_to, $subject, $header . $body . $footer, 0 );

			$this->output_notices( array( __( 'Preview ticket has been sent', 'woocommerce-events' ) ) );

		}
	}

	/**
	 * Get demo details for ticket preview
	 *
	 * @return array
	 */
	private function get_demo_ticket() {

		$ticket = array(
			'WooCommerceEventsDate'                    => '24-11-2020',
			'WooCommerceEventsVariations'              => '',
			'WooCommerceEventsVariationID'             => '',
			'fooevents_custom_attendee_fields_options' => 'Shirt size: L',
			'WooCommerceEventsEvent'                   => 'Event',
			'WooCommerceEventsHour'                    => '13',
			'WooCommerceEventsMinutes'                 => '00',
			'WooCommerceEventsPeriod'                  => '',
			'WooCommerceEventsHourEnd'                 => '14',
			'WooCommerceEventsMinutesEnd'              => '00',
			'WooCommerceEventsEndPeriod'               => '',
			'WooCommerceEventsLocation'                => __( 'Local Stadium', 'woocommerce-events' ),
			'WooCommerceEventsTicketLogo'              => '',
			'WooCommerceEventsTicketHeaderImage'       => '',
			'WooCommerceEventsSupportContact'          => '0841111111',
			'WooCommerceEventsTicketBackgroundColor'   => '#050505',
			'WooCommerceEventsTicketButtonColor'       => '#55AF71',
			'WooCommerceEventsTicketTextColor'         => '#FFFFFF',
			'WooCommerceEventsTicketPurchaserDetails'  => 'on',
			'WooCommerceEventsTicketAddCalendar'       => 'on',
			'WooCommerceEventsTicketDisplayDateTime'   => 'on',
			'WooCommerceEventsTicketDisplayBarcode'    => 'on',
			'WooCommerceEventsTicketText'              => 'This is preview text',
			'WooCommerceEventsDirections'              => 'These are preview directions',
			'WooCommerceEventsTicketDisplayPrice'      => 'on',
			'WooCommerceEventsTicketDisplayZoom'       => 'on',
			'WooCommerceEventsTicketType'              => 'Early Bird',
			'WooCommerceEventsProductID'               => '',
			'WooCommerceEventsTicketID'                => '111111111',
			'WooCommerceEventsOrderID'                 => '',
			'name'                                     => __( 'Preview Event', 'woocommerce-events' ),
			'cancelLink'                               => '',
			'WooCommerceEventsAttendeeName'            => '',
			'WooCommerceEventsAttendeeLastName'        => '',
			'WooCommerceEventsAttendeeTelephone'       => '',
			'WooCommerceEventsAttendeeCompany'         => '',
			'WooCommerceEventsAttendeeDesignation'     => '',
			'WooCommerceEventsAttendeeEmail'           => '',
			'customerFirstName'                        => __( 'John', 'woocommerce-events' ),
			'customerLastName'                         => __( 'Doe', 'woocommerce-events' ),
			'customerEmail'                            => '',
			'FooEventsTicketFooterText'                => '',
			'price'                                    => '$99.00',
			'WooCommerceEventsPrice'                   => '$99.00',
			'WooCommerceEventsTicketDisplayBookings'   => '',
			'WooCommerceEventsTicketDisplayMultiDay'   => '',
			'WooCommerceEventsType'                    => '',
			'TicketNumberTicketOutput'                 => '',
			'ticketNumber'                             => 1,
			'ID'                                       => 0,
			'WooCommerceEventsDisplayPoweredby'        => 'off',

		);

		return $ticket;
	}

	/**
	 * Gets a list of FooEvents Ticket themes
	 */
	public function get_ticket_themes() {

		$valid_themes = array();

		$latest_theme_versions = $this->get_latest_fooevents_themes();

		foreach ( new DirectoryIterator( $this->config->theme_packs_path ) as $file ) {

			if ( $file->isDir() && ! $file->isDot() ) {

				$theme_name = $file->getFilename();

				$theme_path = $file->getPath();
				$theme_path = $theme_path . '/' . $theme_name;

				$theme_name_pretty = str_replace( '_', ' ', $theme_name );
				$theme_name_prep   = ucwords( $theme_name_pretty );

				if ( file_exists( $theme_path . '/header.php' ) && file_exists( $theme_path . '/footer.php' ) && file_exists( $theme_path . '/ticket.php' ) ) {

					$theme_config = array();
					if ( file_exists( $theme_path . '/config.json' ) ) {

						$theme_config                             = file_get_contents( $theme_path . '/config.json' );
						$theme_config                             = json_decode( $theme_config, true );
						$valid_themes[ $theme_name_prep ]['name'] = $theme_config['name'];

						if ( ! empty( $theme_config['version'] ) ) {

							$valid_themes[ $theme_name_prep ]['version'] = $theme_config['version'];

						} else {

							$valid_themes[ $theme_name_prep ]['version'] = 'Legacy';

						}

						if ( ! empty( $theme_config['url'] ) ) {

							$valid_themes[ $theme_name_prep ]['details_url'] = $theme_config['url'];

						} else {

							$valid_themes[ $theme_name_prep ]['details_url'] = esc_url_raw( 'https://help.fooevents.com/docs/topics/changelogs/ticket-themes/' );

						}
					} else {

						$valid_themes[ $theme_name_prep ]['name']    = $theme_name_prep;
						$valid_themes[ $theme_name_prep ]['version'] = 'Legacy';

					}

					$current_version = $valid_themes[ $theme_name_prep ]['version'];
					$latest_version  = '';

					if ( isset( $latest_theme_versions[ $theme_name_prep ]['version'] ) ) {

						$latest_version = $latest_theme_versions[ $theme_name_prep ]['version'];

					}

					if ( version_compare( $current_version, $latest_version, '<' ) ) {

						$valid_themes[ $theme_name_prep ]['update_available'] = true;
						$valid_themes[ $theme_name_prep ]['update_version']   = $latest_version;

					} else {

						$valid_themes[ $theme_name_prep ]['update_available'] = false;

					}

					$valid_themes[ $theme_name_prep ]['path'] = $theme_path;
					$theme_url                                = $this->config->theme_packs_url . $theme_name;
					$valid_themes[ $theme_name_prep ]['url']  = $theme_url;

					if ( file_exists( $theme_path . '/preview.jpg' ) ) {

						$valid_themes[ $theme_name_prep ]['preview'] = $theme_url . '/preview.jpg';

					} else {

						$valid_themes[ $theme_name_prep ]['preview'] = $this->config->event_plugin_url . 'images/no-preview.jpg';

					}

					$valid_themes[ $theme_name_prep ]['file_name'] = $file->getFilename();

				}
			}
		}

		return $valid_themes;
	}

	/**
	 * Adds menu badge with the number of theme updates available.
	 */
	public function add_fooevents_themes_count_badge() {

		global $submenu;
		$cache_key = 'fooevents_themes_update_count';

		$update_count = get_transient( $cache_key );

		if ( false === $update_count ) {
			$themes       = $this->get_ticket_themes();
			$update_count = 0;

			if ( is_array( $themes ) ) {

				foreach ( $themes as $theme ) {

					if ( ! empty( $theme['update_available'] ) && 1 == $theme['update_available'] ) {

						++$update_count;

					}
				}
			}

			set_transient( $cache_key, $update_count, 24 * HOUR_IN_SECONDS );
		}

		if ( $update_count > 0 ) {

			if ( isset( $submenu['fooevents'] ) ) {

				foreach ( $submenu['fooevents'] as $key => $details ) {

					if ( 'Ticket Themes' === $details[0] ) {

						$submenu['fooevents'][ $key ][0] .= sprintf( ' <span class="update-plugins count-%1$s"><span class="plugin-count">%1$s</span></span>', $update_count );

						break;
					}
				}
			}
		}
	}

	/**
	 * Outputs notices to screen.
	 *
	 * @param array $notices notices.
	 */
	private function output_notices( $notices ) {

		foreach ( $notices as $notice ) {

			echo '<div class="updated"><p>' . esc_attr( $notice ) . '</p></div>';

		}
	}
}
