<?php
/**
 * File: Ecre_Generate_Coupon.php
 * Description: This file contains the Ecre_Generate_Coupon class, responsible for generating referral coupons for logged-in users.
 *
 * @package ECRE
 */

namespace ECRE;

if ( ! class_exists( 'Ecre_Generate_Coupon' ) ) {
	/**
	 * Class: Ecre_Generate_Coupon
	 *
	 * The Ecre_Generate_Coupon class handles the generation of referral coupons for logged-in users.
	 *
	 * @package  ECRE
	 */
	class Ecre_Generate_Coupon {
		/**
		 * Holds the settings configuration for the ECRE order tracking system.
		 *
		 * This property stores various settings retrieved from the database,
		 * such as email templates, discount configurations, and tracking options.
		 *
		 * @var array
		 */
		public $settings;

		/**
		 * Holds the settings configuration for the ECRE order tracking system.
		 *
		 * This property stores various settings retrieved from the database,
		 * such as email templates, discount configurations, and tracking options.
		 *
		 * @var array
		 */
		public $is_pro;

		/**
		 * Initializes the Ecre_Generate_Coupon class.
		 *
		 * Sets up the class properties and registers the `init` action hook to automatically
		 * generate referral coupons for logged-in users based on the provided configuration settings.
		 *
		 * @param array $settings Configuration settings for generating referral coupons.
		 * @param bool  $is_pro   Indicates whether the user has a professional (pro) account.
		 *
		 * @since 1.0.0
		 */
		public function __construct( $settings, $is_pro ) {
			$this->settings = $settings;
			$this->is_pro   = $is_pro;
			$this->generate_referral_coupon_for_logged_in_users();
		}

		/**
		 * Function: generate_referral_coupon_for_logged_in_users
		 *
		 * Checks if the user is logged in and generates a referral coupon if the user is a customer or administrator.
		 *
		 * @return void
		 */
		public function generate_referral_coupon_for_logged_in_users() {
			// Check if the user is logged in.
			if ( is_user_logged_in() ) {
				// Get the current user.
				$current_user = wp_get_current_user();

				// Check if the user is a customer or administrator.
				if ( ! empty( $current_user->roles ) ) {
					// Generate the referral coupon.
					$this->generate_referral_coupon( $current_user->ID );
				}
			}
		}

		/**
		 * Function: generate_referral_coupon
		 *
		 * Generates a referral coupon for a given user ID if the user does not already have one.
		 *
		 * @param int $user_id The ID of the user for whom the coupon is generated.
		 *
		 * @return void
		 */
		public function generate_referral_coupon( $user_id ) {
			if ( is_multisite() ) {
				// Get all sites in the network.

				$current_site_id = get_current_blog_id();

				$sites = get_sites();

				foreach ( $sites as $site ) {
					switch_to_blog( $site->blog_id );
					$this->generate_coupon_for_user( $user_id );

					restore_current_blog();
				}
			} else {
				$this->generate_coupon_for_user( $user_id );
			}
		}

		/**
		 * Generates a referral coupon for a given user if the user does not already have one.
		 *
		 * @param int $user_id The ID of the user for whom the coupon is generated.
		 *
		 * @return void
		 */
		private function generate_coupon_for_user( $user_id ) {
			// Check if the user already has a referral coupon on this site.
			$existing_coupon  = $this->get_user_referral_coupon( $user_id );
			$default_settings = ecre_default_settings();

			if ( empty( $existing_coupon ) ) {
				// Generate a new referral coupon.
				$currency_symbol        = ecre_custom_currency_symbol();
				$amount                 = $this->settings['referralDiscount'];
				$settings_discount_type = $this->settings['referralCouponType']['value'];
				$discount_type          = '';
				$coupon_prefix          = '';

				if ( $this->is_pro ) {
					$coupon_prefix = $this->settings['referralCouponPrefix'];
				} else {
					$coupon_prefix = $default_settings['referralCouponPrefix'];
				}

				$generated_coupon = ecre_generate_unique_coupon_code();
				$coupon_code      = $coupon_prefix . $generated_coupon;

				if ( ! $this->is_pro && ( 'percent' !== $settings_discount_type && 'fixed' !== $settings_discount_type ) ) {
					$discount_type = $default_settings['referralCouponType']['value'];
				} else {
					$discount_type = $settings_discount_type;
				}

				$discount                  = ( 'percent' === $discount_type ) ? $amount . '%' : $amount . $currency_symbol;
				$selected_product_ids      = isset( $this->settings['referralIncludeProducts'] ) && is_array( $this->settings['referralIncludeProducts'] ) ? array_column( $this->settings['referralIncludeProducts'], 'value' ) : array();
				$exclude_product_ids       = isset( $this->settings['referralExcludeProducts'] ) && is_array( $this->settings['referralExcludeProducts'] ) ? array_column( $this->settings['referralExcludeProducts'], 'value' ) : array();
				$selected_categories       = isset( $this->settings['referralIncludeCategories'] ) && is_array( $this->settings['referralIncludeCategories'] ) ? array_column( $this->settings['referralIncludeCategories'], 'value' ) : array();
				$exclude_categories        = isset( $this->settings['referralExcludeCategories'] ) && is_array( $this->settings['referralExcludeCategories'] ) ? array_column( $this->settings['referralExcludeCategories'], 'value' ) : array();
				$enable_subscription_limit = $this->settings['enableReferralLimitSubscriptionCoupon'];
				$subscription_limit        = $this->settings['referralLimitSubscriptionCoupon'];

				$coupon = array(
					'post_title'   => $coupon_code,
					'post_content' => $discount . ' off coupon',
					'post_excerpt' => $discount . ' off coupon',
					'post_status'  => 'publish',
					'post_author'  => $user_id,
					'post_type'    => 'shop_coupon',
				);

				$new_coupon_id = wp_insert_post( $coupon );

				update_user_meta( $user_id, 'ecre_referral_coupon', $coupon_code );
				update_post_meta( $new_coupon_id, 'discount_type', $discount_type );
				update_post_meta( $new_coupon_id, 'coupon_amount', $amount );
				update_post_meta( $new_coupon_id, 'individual_use', 'yes' );
				update_post_meta( $new_coupon_id, 'referral_user_id', $user_id );

				// Add user to referrers table when referral coupon is created.
				if ( class_exists( '\ECRE\Ecre_Database' ) ) {
					$database = new \ECRE\Ecre_Database();
					$database->update_dashboard_summary_referrers_on_creation( $user_id, 'increment' );
					$database->store_referrer( $user_id, $coupon_code, $new_coupon_id );
				}

				if ( $this->is_pro && ! empty( $enable_subscription_limit ) ) {
					update_post_meta( $new_coupon_id, '_wcs_number_payments', $subscription_limit );
				}

				if ( ! empty( $selected_product_ids ) ) {
					update_post_meta( $new_coupon_id, 'product_ids', implode( ',', $selected_product_ids ) );
				}

				if ( ! empty( $exclude_product_ids ) ) {
					update_post_meta( $new_coupon_id, 'exclude_product_ids', implode( ',', $exclude_product_ids ) );
				}

				if ( ! empty( $selected_categories ) ) {
					update_post_meta( $new_coupon_id, 'product_categories', $selected_categories );
				}

				if ( ! empty( $exclude_categories ) ) {
					update_post_meta( $new_coupon_id, 'exclude_product_categories', $exclude_categories );
				}
			}
		}

		/**
		 * Function: get_user_referral_coupon
		 *
		 * Helper function to retrieve the user's existing referral coupon, if any.
		 *
		 * @param int $user_id The ID of the user for whom the coupon is retrieved.
		 *
		 * @return object|null The user's referral coupon or null if not found.
		 */
		public function get_user_referral_coupon( $user_id ) {
			$args = array(
				'post_type'  => 'shop_coupon',
				//phpcs:ignore
				'meta_query' => array(
					array(
						'key'   => 'referral_user_id',
						'value' => $user_id,
					),
				),
			);

			$coupons = get_posts( $args );

			if ( ! empty( $coupons ) ) {
				return $coupons[0];
			}

			return null;
		}
	}
}
