<?php
/**
 * Common functions class
 *
 * @package WooCommerce Points and Rewards
 * @version 1.0.0
 */

namespace DDWCPointsAndRewards\Includes\Common;

use DDWCPointsAndRewards\Includes\DDWCPR_Email_Notification_Handler;
use DDWCPointsAndRewards\Helper\Point\DDWCPR_Point_Helper;
use DDWCPointsAndRewards\Helper\Rule\DDWCPR_Rule_Helper;
use DDWCPointsAndRewards\Helper\Log\DDWCPR_Log_Helper;

defined( 'ABSPATH' ) || exit();

if ( ! class_exists( 'DDWCPR_Common_Functions' ) ) {
	/**
	 * Common functions
	 */
	class DDWCPR_Common_Functions {
		/**
		 * Configuration Variable
		 *
		 * @var array
		 */
		protected $ddwcpr_configuration;

		/**
		 * Rule Helper Variable
		 *
		 * @var object
		 */
		protected $rule_helper;

		/**
		 * Point Helper Variable
		 *
		 * @var object
		 */
		protected $point_helper;

		/**
		 * Construct
		 * 
		 * @param array $ddwcpr_configuration
		 */
		public function __construct( $ddwcpr_configuration ) {
			$this->ddwcpr_configuration = $ddwcpr_configuration;
			$this->rule_helper          = new DDWCPR_Rule_Helper( $ddwcpr_configuration );
			$this->point_helper         = new DDWCPR_Point_Helper( $ddwcpr_configuration );
		}

		/**
		 * Add SVG icons
		 *
		 * @param array $default_svg_icons
		 * @param array $args
		 * @return array
		 */
		public function ddwcpr_add_svg_icons( $default_svg_icons, $args ) {
			$size         = ! empty( $args['size'] ) ? $args['size'] : '24';
			$size_attr    = 'width="' . $size . '" height="' . $size . '"';
			$stroke_color = ! empty( $args['stroke_color'] ) ? $args['stroke_color'] : 'currentColor';
			$stroke_width = isset( $args['stroke_width'] ) ? $args['stroke_width'] : '2';
			$fill         = ! empty( $args['fill'] ) ? $args['fill'] : 'none';

			$svg_icons = [
				'display-messages'  => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>',
				'points-earning'    => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><path d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z"></path></svg>',
				'points-redeeming'  => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="8" width="18" height="4" rx="1"></rect><path d="M12 8v13"></path><path d="M19 12v7a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-7"></path><path d="M7.5 8a2.5 2.5 0 0 1 0-5A4.8 8 0 0 1 12 8a4.8 8 0 0 1 4.5-5 2.5 2.5 0 0 1 0 5"></path></svg>',
				'points-expiration' => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>',
				'layout'            => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="18" x="3" y="3" rx="2"></rect><path d="M3 9h18"></path><path d="M9 21V9"></path></svg>',
				'emails'            => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="16" x="2" y="4" rx="2"></rect><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"></path></svg>',
				'shortcodes'        => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>',
				'level' => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><path d="M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z"></path><path d="M5 21h14"></path></svg>',
				'total_earned_points' => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="6"></circle><path d="M18.09 10.37A6 6 0 1 1 10.34 18"></path><path d="M7 6h1v4"></path><path d="m16.71 13.88.7.71-2.82 2.82"></path></svg>',
				'available_points' => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><path d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z"></path></svg>',
				'redeemed_points' => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="8" width="18" height="4" rx="1"></rect><path d="M12 8v13"></path><path d="M19 12v7a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-7"></path><path d="M7.5 8a2.5 2.5 0 0 1 0-5A4.8 8 0 0 1 12 8a4.8 8 0 0 1 4.5-5 2.5 2.5 0 0 1 0 5"></path></svg>',
				'expired_points' => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>',
				'converted_coupons' => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><path d="M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z"></path><path d="M13 5v2"></path><path d="M13 17v2"></path><path d="M13 11v2"></path></svg>',
				'total_referrals' => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M22 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>',
				'copy' => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"></rect><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path></svg>',
				'cloud-upload' => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 56 56" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '"><path xmlns="http://www.w3.org/2000/svg" d="M52 29.3998C52 36.4559 46.2561 42.1998 39.2 42.1998H37.6C36.72 42.1998 36 41.4798 36 40.5998C36 39.7198 36.72 38.9998 37.6 38.9998H39.2C44.4961 38.9998 48.8 34.6959 48.8 29.3998C48.8 25.1437 45.9522 21.3519 41.8878 20.1838C41.2639 20.0077 40.8 19.4638 40.736 18.8077C40.256 13.8959 36.1599 10.1999 31.2 10.1999C27.4561 10.1999 24.0478 12.3759 22.4961 15.7677C22.1921 16.4398 21.4722 16.8077 20.7361 16.6798C20.4961 16.6159 20.2561 16.5998 20 16.5998C17.36 16.5998 15.2 18.7598 15.2 21.3998C15.2 22.1837 14.64 22.9998 13.8561 23.1276C10 23.7676 7.2 27.0798 7.2 30.9998C7.2 35.4159 10.7839 38.9998 15.2 38.9998H18.4C19.28 38.9998 20 39.7198 20 40.5998C20 41.4798 19.28 42.1998 18.4 42.1998H15.2C9.02391 42.1998 4 37.1759 4 30.9998C4 25.9276 7.34391 21.5918 12.0961 20.2478C12.7039 16.3278 16.0161 13.4 20 13.4H20.1121C22.3682 9.48 26.5921 7 31.1997 7C37.4558 7 42.6877 11.4161 43.7757 17.4475C48.6718 19.3197 52 24.0873 52 29.3998ZM29.1364 28.6637C28.9925 28.5197 28.8325 28.4237 28.6564 28.3437C28.6086 28.3276 28.5604 28.3115 28.4964 28.2958C28.3686 28.248 28.2404 28.2319 28.0964 28.2158C28.0486 28.2158 27.9843 28.1997 27.9364 28.1997C27.7604 28.1997 27.6004 28.2319 27.4243 28.2958C27.4082 28.2958 27.3922 28.2958 27.3764 28.3119C27.2004 28.3919 27.0404 28.504 26.9125 28.6319C26.8964 28.648 26.8804 28.648 26.8647 28.664L22.0647 33.464C21.4407 34.088 21.4407 35.0962 22.0647 35.7201C22.3843 36.0398 22.7843 36.1998 23.2004 36.1998C23.6165 36.1998 24.0165 36.0398 24.3365 35.7358L26.4004 33.6558V47.3994C26.4004 48.2794 27.1204 48.9994 28.0004 48.9994C28.8804 48.9994 29.6004 48.2794 29.6004 47.3994V33.6558L31.6643 35.7197C32.2882 36.3437 33.2965 36.3437 33.9204 35.7197C34.5443 35.0958 34.5443 34.0876 33.9204 33.4637L29.1364 28.6637Z"/></svg>',
				'checkmark-circle' => '<svg xmlns="http://www.w3.org/2000/svg" ' . $size_attr . ' viewBox="0 0 24 24" fill="' . $fill . '" stroke="' . $stroke_color . '" stroke-width="' . $stroke_width . '" stroke-linecap="round" stroke-linejoin="round"><path d="M9 12L11 14L15 10M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',
			];

			return array_merge( $default_svg_icons, $svg_icons );
		}

		/**
		 * Add Endpoints function
		 *
		 * @return void
		 */
		public function ddwcpr_add_endpoints() {
			add_rewrite_endpoint( $this->ddwcpr_configuration['my_account_endpoint'], EP_ROOT | EP_PAGES );
		}

		/**
		 * Add Email Notification function
		 *
		 * @param array $email_classes
		 * @return array
		 */
		public function ddwcpr_add_new_email_notification( $email_classes ) {
			$email_classes['WC_Email_DDWCPR_Notification'] = new DDWCPR_Email_Notification_Handler();
			return $email_classes;
		}

		/**
		 * Add Email Notification Action function
		 *
		 * @param array $actions
		 * @return array
		 */
		public function ddwcpr_add_notification_actions( $actions ) {
			$actions[] = 'ddwcpr_mail';
			return $actions;
		}

		/**
		 * Changes status of commissions related to an order, after of a status change for the order function
		 *
		 * @param int    $order_id   Order id.
		 * @param string $old_status Old order status.
		 * @param string $new_status New order status.
		 *
		 * @return void
		 */
		public function ddwcpr_handle_order_status_changed( $order_id, $old_status, $new_status ) {
			$order = wc_get_order( $order_id );

			if ( ! $order ) {
				return;
			}

			if ( $order->has_status( 'trash' ) ) {
				return;
			}

			$earned_points = $order->get_meta( '_ddwcpr_earned_points', true );

			// Award earned points
			if ( in_array( 'wc-' . $new_status, $this->ddwcpr_configuration['award_order_status'], true ) && ! $earned_points ) {
				$points = $this->rule_helper->ddwcpr_calculate_order_earning_points( $order, true );

				if ( $points > 0 ) {

					$data = [
						'points'      => $points,
						'user_id'     => $order->get_customer_id(),
						'related_id'  => $order_id,
						/* translators: %1$d: points, %2$s: points label */
						'description' => sprintf( esc_html__( 'Earned %1$d %2$s for this purchase.', 'loyaltyx-points-and-rewards-for-woocommerce' ), $points, ddwcpr_get_points_label( $points ) ),
						'event'       => 'order_completion',
					];

					$this->point_helper->ddwcpr_add_user_points( $data );

					$order->add_order_note( sprintf( esc_html__( 'Customer have earned %d %s for this purchase.', 'loyaltyx-points-and-rewards-for-woocommerce' ), $points, ddwcpr_get_points_label( $points ) ) );

					$order->update_meta_data( '_ddwcpr_earned_points', $points );
					$order->save();
				}
			}

			// Revoke earned or redeemed points
			if ( in_array( 'wc-' . $new_status, $this->ddwcpr_configuration['revoke_order_status'], true ) && $earned_points ) {
				$earned_points   = $order->get_meta( '_ddwcpr_earned_points', true );
				$revoked_points  = $order->get_meta( '_ddwcpr_revoked_points', true );
				$revoking_points = empty( $revoked_points ) ? $earned_points : $earned_points - $revoked_points;

				if ( $revoking_points > 0 ) {
					// Deduct the points from the customer's balance
					$data = [
						'points'      => -$revoking_points,
						'user_id'     => $order->get_customer_id(),
						'related_id'  => $order_id,
						/* translators: %1$d: points, %2$s: points label, %3$s: order status */
						'description' => sprintf( esc_html__( 'Revocation of %1$d %2$s due to order status %3$s.', 'loyaltyx-points-and-rewards-for-woocommerce' ), $revoking_points, ddwcpr_get_points_label( $revoking_points ), $new_status ),
						'event'       => 'order_' . $new_status,
					];

					$this->point_helper->ddwcpr_deduct_user_points( $data, $order_id );

					/* translators: %1$d: points, %2$s: points label, %3$s: order status */
					$order->add_order_note( sprintf( esc_html__( 'Revocation of %1$d %2$s due to order status %3$s.', 'loyaltyx-points-and-rewards-for-woocommerce' ), $revoking_points, ddwcpr_get_points_label( $revoking_points ), $new_status ) );

					$order->update_meta_data( '_ddwcpr_revoked_points', $revoking_points );
					$order->save();
				}
			}
		}

		/**
		 * Replace coupon label in cart, checkout, and order review function
		 *
		 * @param string $label
		 * @param object $coupon
		 * @return string
		 */
		public function ddwcpr_replace_coupon_label_in_cart_checkout_order_review( $label, $coupon ) {
			$custom_label = get_post_meta( $coupon->get_id(), 'ddwcpr_coupon_label', true );
			if ( ! empty( $custom_label ) ) {
				return esc_html( $custom_label ) . '[' . esc_html( $coupon->get_code() ) . ']';
			}
			return $label;
		}

		/**
		 * Flag order meta if a rewards generated coupon is applied
		 *
		 * @param \WC_Order $order
		 * @param array     $data
		 * @return void
		 */
		public function ddwcpr_flag_order_if_rewards_generated_coupon( $order, $data ) {
			if ( ! $order instanceof \WC_Order ) {
				return;
			}

			$rewards_coupon_ids = [];
			foreach ( $order->get_coupon_codes() as $code ) {
				$coupon = new \WC_Coupon( $code );
				if ( ! $coupon || ! $coupon->get_id() ) {
					continue;
				}
				// Our coupons are generated by rewards and store identifying meta
				$rule_type = get_post_meta( $coupon->get_id(), 'ddwcpr_rule_type', true );
				if ( ! empty( $rule_type ) ) {
					$rewards_coupon_ids[] = (int) $coupon->get_id();
				}
			}

			if ( ! empty( $rewards_coupon_ids ) ) {
				$order->update_meta_data( '_ddwcpr_coupon_applied', 1 );
				$order->update_meta_data( '_ddwcpr_coupon_ids', array_map( 'intval', $rewards_coupon_ids ) );
				$order->save();
			}
		}
	}
}
