<?php
/**
 * Manage the redeem
 *
 */

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

class YWF_Multivendor_Redeem {
	/**
	 * The table name
	 *
	 * @var string
	 */
	protected static $redeem_payments_table_name = 'yith_redeem_funds_payments';

	/**
	 * Init the redeem
	 *
	 * @return void
	 */
	public static function init() {
		$manual_redeem = get_option( 'ywf_enable_manual_redeeming', 'no' );

		self::create_table();
		if ( 'yes' === $manual_redeem ) {
			add_action( 'yith_funds_balance_after_total', array( __CLASS__, 'show_redeem_link' ) );
			add_action( 'wp_enqueue_scripts', array( __CLASS__, 'include_button_style' ), 20 );
			add_action( 'wp_ajax_redeem_funds', array( __CLASS__, 'redeem_funds_ajax' ) );
		} else {
			add_action( 'yith_commission_status_paid', array( __CLASS__, 'redeem_funds_on_threshold' ), 20 );
			add_action( 'wp_loaded', array( __CLASS__, 'redeem_funds_setup_schedule' ) );
			add_action( 'update_option_ywf_redeeming_payment_type', array(
				__CLASS__,
				'redeem_funds_delete_schedule'
			) );
			add_action( 'ywf_redeem_funds_action_schedule', array( __CLASS__, 'redeem_funds_month_cron' ) );


		}
		add_filter( 'yith_payouts_payment_mode', array( __CLASS__, 'add_payouts_redeem_funds_payment_mode' ), 15 );
		add_filter( 'yith_paypal_payout_redeem_funds_items_html', array(
			__CLASS__,
			'get_redeem_funds_items_html'
		), 10, 4 );
		add_filter( 'yith_payouts_items_columns', array( __CLASS__, 'redeem_funds_column_name' ) );
		add_filter( 'ywf_operation_type', array( __CLASS__, 'add_redeem_type' ), 20 );
	}


	/**
	 * Create the Redeem fund payments table
	 *
	 * @author YITH <plugins@yithemes.com>
	 * @since 2.0.0
	 */
	public static function create_table() {

		global $wpdb;

		/**
		 * Check if dbDelta() exists
		 */
		if ( ! function_exists( 'dbDelta' ) ) {
			require_once ABSPATH . 'wp-admin/includes/upgrade.php';
		}

		$charset_collate = $wpdb->get_charset_collate();

		$table_name = $wpdb->prefix . self::$redeem_payments_table_name;
		$create     = "CREATE TABLE IF NOT EXISTS $table_name (
                        ID bigint(20) NOT NULL AUTO_INCREMENT,
                        vendor_id bigint(20) NOT NULL,
                        user_id bigint(20) NOT NULL,
                        amount double(15,4) NOT NULL,
                        currency varchar(10) NOT NULL,
                        status varchar(100) NOT NULL,
                        note text NOT NULL,
                        payment_date DATETIME NOT NULL DEFAULT '000-00-00 00:00:00',
                        payment_date_gmt DATETIME NOT NULL DEFAULT '000-00-00 00:00:00',
                        gateway_id varchar(100),
                        PRIMARY KEY (ID)
                        ) $charset_collate;";
		dbDelta( $create );

	}


	/**
	 * Add custom css in the frontend
	 *
	 * @since 2.0.0
	 */
	public static function include_button_style() {

		$text_color       = get_option(
			'ywf_redeeming_button_text_color',
			array(
				'color'       => '#333333',
				'hover_color' => '#333333',
			)
		);
		$background_color = get_option(
			'ywf_redeeming_button_background_color',
			array(
				'color'       => '#eeeeee',
				'hover_color' => '#d5d5d5',
			)
		);
		$css              = '#yith_redeem_button {
							color : ' . $text_color['color'] . ';
							background: ' . $background_color['color'] . ';
						}

						#yith_redeem_button:hover{
						color : ' . $text_color['hover_color'] . ';
						background: ' . $background_color['hover_color'] . ';
					}';

		wp_add_inline_style( 'ywf_style', $css );

		$params = array(
			'ajax_url'     => admin_url( 'admin-ajax.php', is_ssl() ? 'https' : 'http' ),
			'redirect_url' => wc_get_endpoint_url( yith_account_funds_get_endpoint_slug( 'redeem-funds' ), 'redeem_made' ),
			'actions'      => array(
				'redeem_funds' => 'redeem_funds',
			),
            'close_links'=>array(
                    'success' => _x('Close', 'Link to close the redeem popup when all is ok','yith-woocommerce-account-funds'),
                    'error' => _x('Got it, close', 'Link to close the redeem popup when there is an error','yith-woocommerce-account-funds'),
            )
		);


		wp_enqueue_script( 'ywf_redeem_funds', YITH_YWF_Modules::get_module_assets_url( 'multi-vendor' ) . '/js/' . yit_load_js_file( 'ywf-redeem-funds.js' ), array( 'jquery' ), YITH_FUNDS_VERSION, true );

		wp_localize_script( 'ywf_redeem_funds', 'ywf_redeem_funds_args', $params );

		wp_enqueue_style( 'ywf_redeem_popup', YITH_YWF_Modules::get_module_assets_url( 'multi-vendor' ) . '/css/redeem-popup.css', array(), YITH_FUNDS_VERSION );

	}


	/**
	 * Detect the redeem funds ajax action
	 *
	 * @throws Exception
	 * @since 1.4.0
	 */
	public static function redeem_funds_ajax() {
		check_ajax_referer( 'yith_account_funds-redeem_funds', 'security' );
		if ( isset( $_REQUEST['amount'] ) ) {
			$amount = sanitize_text_field( wp_unslash( $_REQUEST['amount'] ) );
			self::redeem_funds( $amount );
		}
	}


	/**
	 * Redeem funds
	 *
	 * @param float $redeem_amount The redeem amount.
	 * @param int   $user_id The user id.
	 *
	 * @throws Exception The exception.
	 */
	public static function redeem( $redeem_amount, $user_id ) {

		try {
			$vendor = yith_wcmv_get_vendor( $user_id, 'user' );

			if ( $vendor->is_valid() && $vendor->is_owner() ) {
				$args = array(
					'user_id'  => $user_id,
					'currency' => get_option( 'woocommerce_currency' ),
					'amount'   => $redeem_amount,
				);


				$paypal_email = $vendor->get_meta( 'paypal_email' );
				if ( ! empty( $paypal_email ) ) {
					$args['paypal_email'] = $paypal_email;
					$results              =  YITH_Redeem_Funds_with_Payouts()->redeem( array( $args ) );
					if ( $results === true ) {
						wp_send_json_success( array( 'message' => __( 'Funds redeemed successfully!', 'yith-woocommerce-account-funds' ) ) );
					} else {
						throw new Exception( $results );
					}
				} else {
					throw new Exception( __( 'Unable to process this request. No paypal email set up in your account', 'yith-woocommerce-account-funds' ) );
				}
			}

		} catch ( Exception $e ) {
			wp_send_json_error( array( 'message' => $e->getMessage() ) );
		}

	}

	/**
	 * Redeem funds
	 *
	 * @param float $redeem_amount The redeem amount.
	 *
	 * @throws Exception The exception.
	 * @since 1.4.0
	 */
	public static function redeem_funds( $redeem_amount ) {

		try {

			$min_to_redeem    = get_option( 'ywf_min_fund_needs', 50 );
			$max_to_redeem    = get_option( 'ywf_max_fund_redeem', '' );
			$user_id          = get_current_user_id();
			$customer         = new YITH_YWF_Customer( $user_id );
			$funds            = $customer->get_funds();
			$default_currency = get_option( 'woocommerce_currency' );

			if ( $funds < $redeem_amount ) {
				throw  new Exception( __( 'Invalid amount', 'yith-woocommerce-account-funds' ) );

			}
			if ( $redeem_amount < $min_to_redeem ) {
				/* translators: %s is the minimum balance that a vendor can have to redeem */
				throw  new Exception( sprintf( __( 'You can\'t redeem funds because you need at least %s in your balance', 'yith-woocommerce-account-funds' ), wc_price( $min_to_redeem, array( 'currency' => $default_currency ) ) ) );
			}

			if ( ! empty( $max_to_redeem ) && $redeem_amount > $max_to_redeem ) {
				/* translators: %s is the maximum balance that a vendor can have to redeem */
				throw  new Exception( sprintf( __( 'You can redeem at most %s', 'yith-woocommerce-account-funds' ), wc_price( $max_to_redeem, array( 'currency' => $default_currency ) ) ) );

			}

			self::redeem( $redeem_amount, $user_id );

		} catch ( Exception $e ) {
			wp_send_json_error( $e->getMessage(), 'error' );
		}


	}



	/**
	 * Add in the payouts, the redeem funds as payment mode
	 *
	 * @param array $payment_mode The default payment mode.
	 *
	 * @return array
	 * @since 1.4.0
	 */
	public static function add_payouts_redeem_funds_payment_mode( $payment_mode ) {

		if ( ! isset( $payment_mode['redeem_funds'] ) ) {

			$payment_mode ['redeem_funds'] = __( 'Redeem Vendor Funds', 'yith-paypal-payouts-for-woocommerce' );
		}

		return $payment_mode;
	}

	/**
	 * Return as string the redeem funds details for the payout table
	 *
	 * @param string $items The items.
	 * @param string $sender_batch_id Payout sender batch id.
	 * @param array  $payout The payout.
	 * @param array  $payout_item The item.
	 *
	 * @return string
	 * @since 1.4.0
	 */
	public static function get_redeem_funds_items_html( $items, $sender_batch_id, $payout, $payout_item ) {

		$args    = array(
			'sender_batch_id' => $sender_batch_id,
			'fields'          => array( 'sender_item_id', 'amount', 'fee' ),
		);
		$results = YITH_Payout_Items()->get_payout_items( $args );
		if ( count( $results ) > 0 ) {
			$total     = 0;
			$total_fee = 0;
			/* translators: %s the vendor name */
			$href_text = _x( 'Redeem Funds Payment for %s', 'Redeem Funds Payment for Jon Doe', 'yith-woocommerce-account-funds' );

			$vendor_url = admin_url( 'term.php' );
			$url_args   = array(
				'taxonomy' => 'yith_shop_vendor',
				'tag_ID'   => '',
			);

			foreach ( $results as $result ) {

				$user_id      = str_replace( 'redeem_funds_vendor_', '', $result['sender_item_id'] );
				$vendor       = yith_wcmv_get_vendor( $user_id, 'user' );
				$redeem_total = $result['amount'];
				$fee          = isset( $result['fee'] ) ? $result['fee'] : 0;

				$total_fee += $fee;
				$total     += $redeem_total;

				$affiliate_formatted_total = wc_price( $redeem_total );

				$url_args['tag_ID'] = $vendor->get_id();
				$vendor_url         = esc_url( add_query_arg( $url_args, $vendor_url ) );

				$user_info = sprintf( '<a href="%s" target="__blank">%s</a>', $vendor_url, $vendor->get_name() );
				$user_info = sprintf( $href_text, $user_info );

				$items .= '<tr class="wc-order-preview-table__item wc-order-preview-table__item--receiver-commission">
                                                <td class="wc-order-preview-table__column--order_commission">' . $user_info . '
                                                    <p><small>' . $vendor->get_meta( 'paypal_email' ) . '</small></p>
                                                </td>
                                                <td class="wc-order-preview-table__column--total">' . $affiliate_formatted_total . '</td>
								            </tr>';

			}

			$new_formatted_fee = wc_price( $total_fee );

			$items .= '<tr class="wc-order-preview-table__item wc-order-preview-table__item--net-total">
								<td class="wc-order-preview-table__column--order_commission"><strong>' . __( 'Fee', 'yith-paypal-payouts-for-woocommerce' ) . '</strong></td>
								<td class="wc-order-preview-table__column--total">' . $new_formatted_fee . '</td>
								</tr>';

			$new_formatted_total = wc_price( $total + $total_fee );

			$items .= '<tr class="wc-order-preview-table__item wc-order-preview-table__item--net-total">
								<td class="wc-order-preview-table__column--order_commission"><strong>' . __( 'Total transaction', 'yith-paypal-payouts-for-woocommerce' ) . '</strong></td>
								<td class="wc-order-preview-table__column--total">' . $new_formatted_total . '</td>
								</tr>';
		}

		return $items;
	}

	/**
	 * Add in the Payouts table a custom column
	 *
	 * @param array $columns The list column.
	 *
	 * @return array
	 * @since 1.4.0
	 */
	public static function redeem_funds_column_name( $columns ) {

		$columns['order'] = _x( 'Redeem Funds', 'Is the title of PayPal Payout detail', 'yith-woocommerce-account-funds' );

		return $columns;
	}

	/**
	 * Check if possible redeem vendor funds if the threshold is reached, when a commission is paid
	 *
	 * @param int $commission_id The commission id.
	 *
	 * @throws Exception The exception.
	 */
	public static function redeem_funds_on_threshold( $commission_id ) {

		$automatic_redeem_mode = get_option( 'ywf_redeeming_payment_type', 'none' );

		if ( 'automatic' === $automatic_redeem_mode ) {
			$commission = new YITH_Commission( $commission_id );

			$vendor = $commission->get_vendor();

			if ( $vendor->is_valid() ) {
				$user     = $commission->get_user();
				$customer = new YITH_YWF_Customer( $user->ID );

				$funds         = $customer->get_funds();
				$min_to_redeem = get_option( 'ywf_min_fund_needs', 50 );
				$max_to_redeem = get_option( 'ywf_max_fund_redeem', '' );

				if ( $funds >= $min_to_redeem ) {

					if ( ! empty( $max_to_redeem ) && $funds > $max_to_redeem ) {
						$funds = $max_to_redeem;
					}

					$args = array(
						'user_id'  => $user->ID,
						'amount'   => $funds,
						'currency' => get_option( 'woocommerce_currency' ),
					);


					$paypal_email = $vendor->paypal_email;

					if ( ! empty( $paypal_email ) ) {
						$args['paypal_email'] = $paypal_email;
						YITH_Redeem_Funds_with_Payouts()->redeem( array( $args ) );
					}
				}
			}
		}
	}

	/**
	 * Setup the redeem cron
	 *
	 * @since 1.4.0
	 */
	public static function redeem_funds_setup_schedule() {

		$automatic_redeem_mode = get_option( 'ywf_redeeming_payment_type', 'none' );

		if ( 'automatic_with_date' === $automatic_redeem_mode && ! wp_next_scheduled( 'ywf_redeem_funds_action_schedule' ) ) {
			wp_schedule_event( time(), 'daily', 'ywf_redeem_funds_action_schedule' );
		}
	}

	/**
	 * Delete the current redeem cron
	 *
	 * @since 1.4.0
	 */
	public static function redeem_funds_delete_schedule() {

		wp_clear_scheduled_hook( 'ywf_redeem_funds_action_schedule' );
	}

	/**
	 * Process the monthly redeem funds action
	 *
	 * @throws Exception The exception.
	 * @since  1.4.0
	 */
	public static function redeem_funds_month_cron() {

		$automatic_redeem_mode = get_option( 'ywf_redeeming_payment_type', 'none' );

		if ( 'automatic_with_date' === $automatic_redeem_mode ) {

			$today               = gmdate( 'j' ); // get the current day.
			$how_days_this_month = gmdate( 't' );// get the number days of current month.
			$day_to_check        = get_option( 'ywf_redeeming_day', 15 );

			// manage exception for February and for months with 30 days.
			$day_to_check = $day_to_check > $how_days_this_month ? $how_days_this_month : $day_to_check;

			if ( $today === $day_to_check ) {
				$vendors       = yith_wcmv_get_vendors();
				$vendor_data   = array();
				$min_to_redeem = get_option( 'ywf_min_fund_needs', 50 );
				$max_to_redeem = get_option( 'ywf_max_fund_redeem', '' );
				/**
				 * The vendor
				 *
				 * @var $vendor YITH_Vendor
				 */
				foreach ( $vendors as $vendor ) {
					$user_id  = $vendor->get_owner();
					$customer = new YITH_YWF_Customer( $user_id );
					$funds    = $customer->get_funds();

					if ( $funds >= $min_to_redeem ) {

						if ( ! empty( $max_to_redeem ) && $funds > $max_to_redeem ) {
							$funds = $max_to_redeem;
						}

						$args = array(
							'user_id'  => $user_id,
							'amount'   => $funds,
							'currency' => get_option( 'woocommerce_currency' ),
						);


						$paypal_email = $vendor->paypal_email;

						if ( ! empty( $paypal_email ) ) {
							$args['paypal_email'] = $paypal_email;
						}
					}
					$vendor_data[] = $args;
				}
			}

			YITH_Redeem_Funds_with_Payouts()->redeem( $vendor_data );

		}

	}


	/**
	 * Show the redeem link inside the "user balance" shortcode
	 *
	 * @return void
	 */
	public static function show_redeem_link() {

		$user_id        = get_current_user_id();
		$customer       = new YITH_YWF_Customer( $user_id );
		$fund_available = $customer->get_funds();
		if ( $fund_available > 0 ) {
			?>
            <div class="yith_funds_balance_redeem">
                <a href="#" class="yith-funds-redeem">Redeem your funds!</a>
            </div>
			<?php
			$min_to_redeem    = get_option( 'ywf_min_fund_needs', 50 );
			$max_to_redeem    = get_option( 'ywf_max_fund_redeem', '' );
			$funds_to_redeem  = min( $max_to_redeem, $fund_available );
			$lang             = isset( $_GET['lang'] ) ? sanitize_text_field( wp_unslash( $_GET['lang'] ) ) : false;
			$currencies       = get_woocommerce_currencies();
			$default_currency = get_option( 'woocommerce_currency' );
			$current_currency = get_woocommerce_currency();
			$error_message    = '';
			$currency_notice  = '';
			$button_label     = get_option( 'ywf_redeeming_button_label', 'Redeem funds!' );
			if ( $default_currency !== $current_currency ) {
				$currency_symbol = get_woocommerce_currency_symbol( $default_currency );
				$currency_notice = sprintf( _x( 'In this page, your funds are in %1$s (%2$s), because the redeem action is available only with this currency', 'In this page, your funds are in United States Dollar ($), because the redeem is possible only with this currency', 'yith-woocommerce-account-funds' ), $currencies[ $default_currency ], $currency_symbol );
			} else {
				$currency_symbol = get_woocommerce_currency_symbol( $current_currency );
			}

			if ( $fund_available > 0 && $fund_available < $min_to_redeem ) {
				$error_message = sprintf( __( 'You don\'t have enough funds to redeem. Minimum balance required to redeem is %1$s', 'yith-woocommerce-account-funds' ), wc_price( $min_to_redeem, array( 'currency' => $default_currency ) ) );
			}
			ob_start();
			include_once YITH_FUNDS_INC . 'modules/multi-vendor/templates/redeem-popup.php';
			$template = ob_get_clean();
			echo $template;
		}
	}


	/**
	 * Add the fiter type for funds history
	 *
	 * @param array $types The filters.
	 *
	 * @return array
	 */
	public static function add_redeem_type( $types ) {
		$types['redeem_vendor_funds'] = _x( 'Redeems', '[Frontend Funds history] Redeem filter type', 'yith-woocommerce-account-funds' );

		return $types;
	}

}