<?php

/**
 * Class ETM_Woocommerce_Emails
 *
 * This class handles WooCommerce email-related functionalities for eTranslation Multilingual.
 */
class ETM_Woocommerce_Emails {

	/**
	 * Constructor function.
	 */
	public function __construct(){}

	/**
	 * Initializes hooks for email-related actions.
	 */
	public function initialize_hooks() {

		// Save current language for user every time wp_footer is loaded
		add_action( 'wp_footer', array( $this, 'save_current_language' ) );

		// In order for the email translation to work properly, WC_VERSION needs to be >= 6.8.0
		if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '6.8.0' ) >= 0 ) {

			// Save user language on checkout
			add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'save_language_on_checkout' ), 10, 2 );
			add_action( 'woocommerce_store_api_checkout_update_order_meta', array( $this, 'save_language_on_checkout_store_api' ), 10, 1 );

			// WooCommerce email notifications
			add_action( 'woocommerce_order_status_processing_to_cancelled_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_status_on-hold_to_cancelled_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_status_completed_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_status_cancelled_to_on-hold_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_status_cancelled_to_processing_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_status_failed_to_processing_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_status_on-hold_to_processing_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_fully_refunded_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_partially_refunded_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_status_pending_to_failed_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_status_on-hold_to_failed_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_status_pending_to_completed_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_status_failed_to_completed_notification', array( $this, 'store_email_order_id' ), 5, 1 );
			add_action( 'woocommerce_order_status_cancelled_to_completed_notification', array( $this, 'store_email_order_id' ), 5, 1 );

			// WooCommerce emails when resent by admin
			add_action( 'woocommerce_before_resend_order_emails', array( $this, 'prepare_order_id_for_resend_emails' ), 5, 2 );
			// WooCommerce note to customer email
			add_action( 'woocommerce_new_customer_note_notification', array( $this, 'prepare_order_id_for_note_emails' ), 5, 1 );

			// Hijack execution to translate emails in user language accordingly
			add_filter( 'woocommerce_allow_switching_email_locale', array( $this, 'etm_woo_setup_locale' ), 10, 2 );
			add_filter( 'woocommerce_allow_restoring_email_locale', array( $this, 'etm_woo_restore_locale' ), 10, 2 );
		}
	}

	/**
	 * Save user language on WooCommerce checkout
	 *
	 * @param $order_id
	 * @param $posted
	 * @return void
	 */
	public function save_language_on_checkout( $order_id, $posted ) {
		global $ETM_LANGUAGE, $ETM_EMAIL_ORDER;
		$order   = wc_get_order( $order_id );
		$user_id = $order->get_user_id();

		$ETM_EMAIL_ORDER = $order_id;
		if ( $user_id != 0 ) {

			$user_preferred_language  = get_user_meta( $user_id, 'etm_language', true );
			$always_use_this_language = get_user_meta( $user_id, 'etm_always_use_this_language', true );

			if ( ! empty( $always_use_this_language ) && $always_use_this_language == 'yes' && ! empty( $user_preferred_language ) ) {
				update_user_meta( $user_id, 'etm_language', $user_preferred_language );
				etm_woo_hpos_manipulate_post_meta( $order_id, 'etm_language', $user_preferred_language, 'update' );

			} else {
				update_user_meta( $user_id, 'etm_language', $ETM_LANGUAGE );
				etm_woo_hpos_manipulate_post_meta( $order_id, 'etm_language', $ETM_LANGUAGE, 'update' );
			}
		} else {
			etm_woo_hpos_manipulate_post_meta( $order_id, 'etm_language', $ETM_LANGUAGE, 'update' );
		}
	}

	/**
	 * Fires when the Checkout Block/Store API updates an order's meta data.
	 *
	 * @param $order
	 * @return void
	 */
	public function save_language_on_checkout_store_api( $order ) {
		global $ETM_LANGUAGE, $ETM_EMAIL_ORDER;
		$user_id         = $order->get_user_id();
		$order_id        = $order->get_id();
		$ETM_EMAIL_ORDER = $order_id;
		if ( $user_id != 0 ) {

			$user_preferred_language  = get_user_meta( $user_id, 'etm_language', true );
			$always_use_this_language = get_user_meta( $user_id, 'etm_always_use_this_language', true );

			if ( ! empty( $always_use_this_language ) && $always_use_this_language == 'yes' && ! empty( $user_preferred_language ) ) {
				update_user_meta( $user_id, 'etm_language', $user_preferred_language );
				etm_woo_hpos_manipulate_post_meta( $order_id, 'etm_language', $user_preferred_language, 'update' );
			} else {
				update_user_meta( $user_id, 'etm_language', $ETM_LANGUAGE );
				etm_woo_hpos_manipulate_post_meta( $order_id, 'etm_language', $ETM_LANGUAGE, 'update' );
			}
		} else {
			etm_woo_hpos_manipulate_post_meta( $order_id, 'etm_language', $ETM_LANGUAGE, 'update' );
		}
	}

	/**
	 * Save current user language
	 *
	 * The hook was added on 'wp_footer' to prevent logout or backend admin actions from resetting $ETM_LANGUAGE to ETM default language
	 *
	 * @return void
	 */
	public function save_current_language() {
		global $ETM_LANGUAGE;
		$user_id = get_current_user_id();

		if ( $user_id > 0 ) {
			$language_meta            = get_user_meta( $user_id, 'etm_language', true );
			$always_use_this_language = get_user_meta( $user_id, 'etm_always_use_this_language', true );

			if ( $language_meta != $ETM_LANGUAGE && $always_use_this_language !== 'yes' ) {
				update_user_meta( $user_id, 'etm_language', $ETM_LANGUAGE );
			}
		}
	}

	/**
	 * Store order id in a separate global to access its value later in the execution
	 *
	 * @param $order_id
	 * @return void
	 */
	public function store_email_order_id( $order_id ) {
		global $ETM_EMAIL_ORDER;
		$ETM_EMAIL_ORDER = $order_id;
	}

	/**
	 * Prepare order id for resend emails
	 *
	 * @param $order
	 * @param $email_type
	 * @return void
	 */
	public function prepare_order_id_for_resend_emails( $order, $email_type ) {
		if ( $email_type == 'customer_invoice' ) {
			$this->store_email_order_id( $order->get_id() );
		}
	}

	/**
	 * Prepare order id for note emails
	 *
	 * @param $note_and_order_id
	 * @return void
	 */
	public function prepare_order_id_for_note_emails( $note_and_order_id ) {
		$this->store_email_order_id( $note_and_order_id['order_id'] );
	}

	/**
	 * Set the language for WooCommerce emails according to the user information:
	 * user profile language for admin AND language metadata for customer
	 *
	 * @param $bool
	 * @param $wc_email
	 * @return false
	 */
	public function etm_woo_setup_locale( $bool, $wc_email ) {
		// We need to set up the $recipients ourselves in case we're dealing with an order.
		// Otherwise, $wc_email->get_recipient() returns null and throws a PHP warning inside WooCommerce /woocommerce/includes/emails/class-wc-email.php
		global $ETM_EMAIL_ORDER;
		$order = false;

		if ( $ETM_EMAIL_ORDER ) {
			$order = wc_get_order( $ETM_EMAIL_ORDER );
		}

		if ( is_a( $order, 'WC_Order' ) ) {
			$recipients = $order->get_billing_email();
		} else {
			$recipients = $wc_email->get_recipient();
		}

		global $ETM_LANGUAGE;
		$is_customer_email = $wc_email->is_customer_email();

		if ( $recipients === null || $recipients === '' ) {
			$recipients = array();
		} elseif ( ! is_array( $recipients ) ) {
			$recipients = explode( ',', $recipients );
		}

		$language = $ETM_LANGUAGE;
		$user_id  = 0;

		if ( $is_customer_email ) {
			if ( $order ) {
				$user_id = $order->get_user_id();
				if ( $user_id > 0 ) {
					$language = get_user_meta( $user_id, 'etm_language', true );
				} else {
					$language = etm_woo_hpos_get_post_meta( $ETM_EMAIL_ORDER, 'etm_language', true );
				}
			}
		} else {
			if ( ! empty( $recipients ) && count( $recipients ) == 1 ) {
				$registered_user = get_user_by( 'email', $recipients[0] );
				if ( $registered_user ) {
					$language = $registered_user->locale;
				} else {
					$language = etm_woo_hpos_get_post_meta( $ETM_EMAIL_ORDER, 'etm_language', true );
				}
			}
		}

		$language = apply_filters( 'etm_woo_email_language', $language, $is_customer_email, $recipients, $user_id );

		if ( empty( $language ) ) {
			$language = $ETM_LANGUAGE;
		}

		etm_switch_language( $language );

		WC()->load_plugin_textdomain();

		// calls necessary because the default additional_content field of an email is localized before this point and stored in a variable in the previous locale
		$wc_email->init_form_fields();
		$wc_email->init_settings();

		return false;

	}


	/**
	 * Restore locale after email is sent
	 *
	 * @param $bool
	 * @param $wc_email
	 * @return false
	 */
	public function etm_woo_restore_locale( $bool, $wc_email ) {

		etm_restore_language();
		WC()->load_plugin_textdomain();

		return false;

	}

}
