<?php // phpcs:ignore WordPress.Files.FileName
/**
 * The class that manage admin features
 *
 * @package YITH\PayPalPayouts\Classes
 */

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

if ( ! class_exists( 'YITH_PayPal_PayOuts_Admin' ) ) {
	/**
	 * Class YITH_PayPal_PayOuts_Admin
	 */
	class YITH_PayPal_PayOuts_Admin {

		/**
		 * The plugin panel object.
		 *
		 * @var YIT_Panel
		 */
		protected $panel;

		/**
		 * The paypal payouts panel page
		 *
		 * @var string
		 */
		protected $panel_page = 'yith_wc_paypal_payouts_panel';

		/**
		 * YITH_PayPal_PayOuts_Admin constructor.
		 */
		public function __construct() {
			// Add action links.
			add_filter( 'plugin_action_links_' . plugin_basename( YITH_PAYOUTS_DIR . '/' . basename( YITH_PAYOUTS_FILE ) ), array(
				$this,
				'action_links'
			) );
			add_filter( 'yith_show_plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 5 );

			// Add action menu.
			add_action( 'admin_menu', array( $this, 'add_menu_page' ), 5 );

			add_action( 'woocommerce_admin_field_yith_payouts_receiver_list', array(
				$this,
				'add_custom_field_types'
			) );
			add_action( 'woocommerce_admin_field_webook-info', array( $this, 'add_custom_field_webhook' ) );

			add_action( 'admin_enqueue_scripts', array( $this, 'include_admin_scripts' ), 20 );

			// Add a new row in the receiver table.
			add_action( 'wp_ajax_save_receiver', array( $this, 'save_receiver' ) );
			add_action( 'wp_ajax_get_payout_item_details', array( $this, 'get_payout_details' ) );
			add_action( 'wp_ajax_generate_payouts', array( $this, 'generate_payouts' ) );
			add_action( 'admin_init', array( $this, 'handler_payouts_actions' ) );
			add_action( 'admin_init', array( $this, 'handler_receiver_actions' ) );

			add_action( 'yith_payouts_list', array( $this, 'show_payouts_list_table' ), 10 );
			add_action( 'yith_payout_receiver_list', array( $this, 'show_payout_receiver_list_table' ), 10 );

			add_filter( 'yith_plugin_fw_yith-plugins_page_yith_wc_paypal_payouts_panel_bulk_delete_confirmation_enabled', '__return_true' );

			add_action( 'admin_action_payouts_download_file', array( $this, 'download_csv_file' ) );

		}

		/**
		 * Action Links.
		 * Add the action links to plugin admin page.
		 *
		 * @param array $links array with plugin links.
		 *
		 * @return array
		 * @author   YITH <plugins@yithemes.com>
		 * @since    1.0
		 */
		public function action_links( $links ) {

			$links = yith_add_action_links( $links, $this->panel_page, true, YITH_PAYOUTS_SLUG );

			return $links;
		}

		/**
		 * Plugin_row_meta.
		 *
		 * Add the action links to plugin admin page.
		 *
		 * @param array $new_row_meta_args The new plugin meta.
		 * @param array $plugin_meta The plugin meta.
		 * @param string $plugin_file The filename of plugin.
		 * @param array $plugin_data The plugin data.
		 * @param string $status The plugin status.
		 * @param string $init_file The filename of plugin.
		 *
		 * @return   array
		 * @since    1.0
		 * @use plugin_row_meta
		 */
		public function plugin_row_meta( $new_row_meta_args, $plugin_meta, $plugin_file, $plugin_data, $status, $init_file = 'YITH_PAYOUTS_INIT' ) {

			if ( defined( $init_file ) && constant( $init_file ) === $plugin_file ) {
				$new_row_meta_args['slug']       = YITH_PAYOUTS_SLUG;
				$new_row_meta_args['is_premium'] = true;
			}

			return $new_row_meta_args;
		}

		/**
		 * Add the menu page under YITH menu
		 *
		 * @since 1.0.0
		 */
		public function add_menu_page() {

			if ( ! empty( $this->panel ) ) {
				return;
			}

			$admin_tabs = array(
				'general-settings'    => __( 'General Settings', 'yith-paypal-payouts-for-woocommerce' ),
				'payout-receivers'    => __( 'Receivers', 'yith-paypal-payouts-for-woocommerce' ),
				'payout-list'         => __( 'Payouts', 'yith-paypal-payouts-for-woocommerce' ),
				'payout-notification' => __( 'Notifications', 'yith-paypal-payouts-for-woocommerce' ),
				'privacy-settings'    => __( 'GDPR', 'yith-paypal-payouts-for-woocommerce' ),
			);

			$args = array(
				'create_menu_page' => true,
				'parent_slug'      => '',
				'page_title'       => 'YITH PayPal Payouts for WooCommerce',
				'menu_title'       => 'PayPal Payouts',
				'capability'       => apply_filters( 'yith_payouts_panel_capability', 'manage_options' ),
				'parent'           => '',
				'parent_page'      => 'yith_plugin_panel',
				'page'             => $this->panel_page,
				'admin-tabs'       => $admin_tabs,
				'options-path'     => YITH_PAYOUTS_DIR . '/plugin-options',
				'class'            => function_exists( 'yith_set_wrapper_class' ) ? yith_set_wrapper_class() : '',
				'is_premium'       => true,
				'plugin_slug'      => YITH_PAYOUTS_SLUG,
			);

			$this->panel = new YIT_Plugin_Panel_WooCommerce( $args );
		}

		/**
		 * Add custom field in plugin options
		 *
		 * @param array $option The field args.
		 *
		 * @since 1.0.0
		 */
		public function add_custom_field_types( $option ) {
			$option['option'] = $option;
			wc_get_template( 'yith_payouts_receiver_list.php', $option, YITH_PAYOUTS_DIR . '/plugin-options/types/', YITH_PAYOUTS_DIR . '/plugin-options/types/' );
		}

		/**
		 * Register scripts and style in admin
		 *
		 * @since 1.0.0
		 */
		public function include_admin_scripts() {

			ob_start();
			include YITH_PAYOUTS_TEMPLATE_PATH . 'admin/payouts-generator-modal.php';
			$template = ob_get_contents();
			ob_end_clean();
			$script_args = array(
				'admin_url'       => admin_url( 'admin-ajax.php', is_ssl() ? 'https' : 'http' ),
				'actions'         => array(
					'save_receiver'    => 'save_receiver',
					'generate_payouts' => 'generate_payouts',
				),
				'nonces'          => array(
					'save_receiver'    => wp_create_nonce( 'save-receiver' ),
					'generate_payouts' => wp_create_nonce( 'generate-payouts' ),
				),
				'receiver_popup'  => array(
					'edit_title' => __( 'Edit receiver', 'yith-paypal-payouts-for-woocommerce' ),
					'new_title'  => __( 'Add receiver', 'yith-paypal-payouts-for-woocommerce' ),
					'footer'     => '<input type="button" class="yith-plugin-fw__button--primary yith-plugin-fw__button--xl receiver-modal-submit" value="' . esc_html__( 'Save', 'yith-paypal-payouts-for-woocommerce' ) . '">',
				),
				'generator_modal' => array(
					'title'   => __( 'Add payouts', 'yith-paypal-payouts-for-woocommerce' ),
					'content' => $template,
				),
			);

			wp_register_script( 'yith_payouts_admin_panel', YITH_PAYOUTS_ASSETS_URL . 'js/' . yit_load_js_file( 'yith_payouts_admin.js' ), array( 'jquery' ), YITH_PAYOUTS_VERSION, true );
			wp_localize_script( 'yith_payouts_admin_panel', 'payouts_admin', $script_args );

			wp_register_style( 'yith_payouts_admin_style', YITH_PAYOUTS_ASSETS_URL . 'css/yith_payouts_admin.css', array(), YITH_PAYOUTS_VERSION );
			wp_register_style( 'yith_payouts_status', YITH_PAYOUTS_ASSETS_URL . 'css/payouts-status.css', array(), YITH_PAYOUTS_VERSION );

			if ( isset( $_GET['page'] ) && 'yith_wc_paypal_payouts_panel' === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

				wp_enqueue_script( 'yith_payouts_admin_panel' );
				wp_enqueue_style( 'yith_payouts_admin_style' );
				wp_enqueue_style( 'yith_payouts_status' );
				wp_enqueue_script( 'yith-plugin-fw-wp-pages' );
			}

			$script_args['actions'] = array(
				'payouts_get_payout_item_details' => 'get_payout_item_details',
			);

			wp_register_script(
				'yith_payouts_preview_modal',
				YITH_PAYOUTS_ASSETS_URL . 'js/' . yit_load_js_file( 'yith_payout_modal_preview.js' ),
				array(
					'jquery',
					'wp-util',
					'underscore',
					'backbone',
					'jquery-blockui',
					'wc-backbone-modal',
				),
				YITH_PAYOUTS_VERSION,
				true
			);
			wp_localize_script( 'yith_payouts_preview_modal', 'payouts_modal', $script_args );
			if ( isset( $_GET['page'] ) && 'yith_wc_paypal_payouts_panel' === $_GET['page'] && isset( $_GET['show_payout_details'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

				wp_enqueue_script( 'yith_payouts_preview_modal' );
			}

		}

		/**
		 * Update the receiver info
		 *
		 * @throws Exception The exception.
		 * @since 2.0.0
		 */
		public function save_receiver() {

			check_ajax_referer( 'save-receiver', 'security' );
			try {
				if ( isset( $_REQUEST['user_id'], $_REQUEST['paypal_email'], $_REQUEST['commission_rate'] ) ) {
					$user_id         = sanitize_text_field( wp_unslash( $_REQUEST['user_id'] ) );
					$paypal_email    = sanitize_text_field( wp_unslash( $_REQUEST['paypal_email'] ) );
					$commission_rate = sanitize_text_field( wp_unslash( $_REQUEST['commission_rate'] ) );
					$user_id         = intval( $user_id );

					if ( empty( $paypal_email ) || ! is_email( $paypal_email ) ) {
						throw new Exception( _x( 'Please, enter a valid PayPal email address.', '[Admin]PayPal email error message', 'yith-paypal-payouts-for-woocommerce' ), 100 );
					}
					if ( empty( $commission_rate ) || ! is_numeric( $commission_rate ) || $commission_rate > 100 ) {
						throw new Exception( _x( 'Please, enter a valid commission rate.', '[Admin]Commission rate error message', 'yith-paypal-payouts-for-woocommerce' ), 200 );
					}
					$receivers = get_option( 'yith_payouts_receiver_list', array() );
					$updated   = false;
					foreach ( $receivers as $key => $receiver ) {
						if ( intval( $receiver['user_id'] ) === $user_id ) {
							$receiver['paypal_email']    = $paypal_email;
							$receiver['commission_rate'] = $commission_rate;
							$receivers[ $key ]           = $receiver;
							$updated                     = true;
							break;
						}
					}

					// If is a new entry check if need create a new customer or not.
					if ( ! $updated ) {
						if ( - 1 === $user_id ) { // Need to create a new user, so create it!.
							$email    = ! empty( $_POST['new_customer_email'] ) ? sanitize_text_field( wp_unslash( $_POST['new_customer_email'] ) ) : '';
							$username = ! empty( $_POST['new_customer_username'] ) ? sanitize_text_field( wp_unslash( $_POST['new_customer_username'] ) ) : '';
							$password = ! empty( $_POST['new_customer_password'] ) ? wp_unslash( $_POST['new_customer_password'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

							// Start build new customer data.
							$new_customer_data = array(
								'first_name' => ! empty( $_POST['new_customer_first_name'] ) ? sanitize_text_field( wp_unslash( $_POST['new_customer_first_name'] ) ) : '',
								'last_name'  => ! empty( $_POST['new_customer_last_name'] ) ? sanitize_text_field( wp_unslash( $_POST['new_customer_last_name'] ) ) : '',
							);
							if ( empty( $email ) || ! is_email( $email ) ) {
								throw new Exception( _x( 'Please, enter a valid email address.', '[Admin]Registration customer error message', 'yith-paypal-payouts-for-woocommerce' ), 150 );
							}

							if ( email_exists( $email ) ) {
								throw new Exception( _x( 'An account with this email address already exists.', '[Admin]Registration customer error message', 'yith-paypal-payouts-for-woocommerce' ), 150 );
							}

							if ( 'yes' === get_option( 'woocommerce_registration_generate_username', 'yes' ) && empty( $username ) ) {
								$username = wc_create_new_customer_username( $email, $new_customer_data );
							}

							$username = sanitize_user( $username );
							if ( empty( $username ) || ! validate_username( $username ) ) {
								throw new Exception( _x( 'Please, enter a valid username.', '[Admin]Registration customer error message', 'yith-paypal-payouts-for-woocommerce' ), 300 );
							}

							if ( username_exists( $username ) ) {
								throw new Exception( _x( 'An account with that username already exists. Please, choose another username.', '[Admin]Registration customer error message', 'yith-paypal-payouts-for-woocommerce' ), 300 );
							}

							// Handle password creation.
							$password_generated = ! empty( $password );
							if ( 'yes' === get_option( 'woocommerce_registration_generate_password' ) && empty( $password ) ) {
								$password           = wp_generate_password();
								$password_generated = true;
							}

							if ( empty( $password ) ) {
								throw new Exception( _x( 'Please, enter an account password.', '[Admin]Registration customer error message', 'yith-paypal-payouts-for-woocommerce' ), 400 );
							}

							// New owner data. Set customer as starting role to prevent wrong role if customer creation process failed.
							$new_customer_data = apply_filters(
								'woocommerce_new_customer_data',
								array_merge(
									$new_customer_data,
									array(
										'user_login' => $username,
										'user_pass'  => $password,
										'user_email' => $email,
										'role'       => 'customer',
									)
								)
							);

							$user_id = wp_insert_user( $new_customer_data );
							if ( is_wp_error( $user_id ) ) {
								throw new Exception( $user_id->get_error_message() );
							}

							do_action( 'woocommerce_created_customer', $user_id, $new_customer_data, $password_generated );

							$owner = new WC_Customer( $user_id );

						}
						$receivers[] = array(
							'user_id'         => $user_id,
							'paypal_email'    => $paypal_email,
							'commission_rate' => $commission_rate,
						);
					}
					update_option( 'yith_payouts_receiver_list', $receivers );

					wp_send_json_success();
				}
			} catch ( Exception $e ) {
				$error_code = $e->getCode();
				$codes      = array(
					100 => 'customer_paypal_email',
					200 => 'customer_commission_rate',
					150 => 'new_customer_email',
					300 => 'new_customer_username',
					400 => 'new_customer_password',
				);

				wp_send_json_error(
					array(
						'message' => $e->getMessage(),
						'field'   => isset( $codes[ $error_code ] ) ? $codes[ $error_code ] : '',
					)
				);
			}
		}

		/**
		 * Show the payout list
		 *
		 * @since 1.0.0
		 */
		public function show_payouts_list_table() {
			ob_start();
			require_once YITH_PAYOUTS_TEMPLATE_PATH . '/admin/payouts-list.php';
			$template = ob_get_contents();
			ob_end_clean();
			echo $template; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
		}

		/**
		 * Show the receiver list
		 *
		 * @since 2.0.0
		 */
		public function show_payout_receiver_list_table() {
			require_once YITH_PAYOUTS_TEMPLATE_PATH . '/admin/payout-receiver-list.php';
		}

		/**
		 * Get the payout details
		 *
		 * @since 1.0.0
		 */
		public function get_payout_details() {

			if ( isset( $_GET['payout_item_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

				include_once 'class.yith-payout-items-list-table.php';
				new YITH_PayOut_Items_List_Table( array( 'screen' => 'payouts_item_list' ) );
				wp_send_json_success( YITH_PayOut_Items_List_Table::payout_item_preview_get_payout_item_details( wp_unslash( $_GET['payout_item_id'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
			}
			die();
		}

		/**
		 * Update the payout status via ajx
		 *
		 * @since 2.0.0
		 */
		public function handler_payouts_actions() {
			if ( isset( $_REQUEST['yith_payouts_action'] ) ) {
				$action = sanitize_text_field( wp_unslash( $_REQUEST['yith_payouts_action'] ) );
				switch ( $action ) {
					case 'update_status':
						if ( isset( $_REQUEST['yith_payouts_update_status_nonce'] ) ) {
							wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['yith_payouts_update_status_nonce'] ) ), 'payouts_update_status' );
							if ( isset( $_REQUEST['batch_id'] ) ) {
								$batch_id = sanitize_text_field( wp_unslash( $_REQUEST['batch_id'] ) );
								YITH_PayOuts_Service()->check_payout_status( $batch_id );
								$url = remove_query_arg( array(
									'batch_id',
									'yith_payouts_action',
									'yith_payouts_update_status_nonce'
								) );
								wp_safe_redirect( $url );
								exit;
							}
						}
						break;
					case 'delete_payout':
						if ( isset( $_REQUEST['yith_payouts_delete_nonce'] ) ) {
							wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['yith_payouts_delete_nonce'] ) ), 'delete_payout' );
							if ( isset( $_REQUEST['payout_id'] ) ) {
								YITH_Payouts::delete_payout( sanitize_text_field( wp_unslash( $_REQUEST['payout_id'] ) ) );
								$url = remove_query_arg( array(
									'payout_id',
									'yith_payouts_action',
									'yith_payouts_delete_nonce'
								) );
								wp_safe_redirect( $url );
								exit;
							}
						}
						break;
					case 'pay_payouts':
						if ( isset( $_REQUEST['yith_payouts_pay_nonce'] ) ) {
							wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['yith_payouts_pay_nonce'] ) ), 'pay_payouts' );
							if ( isset( $_REQUEST['sender_batch_id'] ) ) {
								$sender_batch_id = sanitize_text_field( wp_unslash( $_REQUEST['sender_batch_id'] ) );
								$args            = array(
									'sender_batch_id' => $sender_batch_id,
									'sender_items'    => YITH_PayOuts_Service()->get_payout_items_by_sender_batch_id( $sender_batch_id ),
								);

								$res = YITH_PayOuts_Service()->PayOuts( $args );
								if ( true !== $res ) {
									yith_payouts_add_error( $res );
								} else {
									yith_payouts_add_message( __( 'Payouts paid successfully', 'yith-paypal-payouts-for-woocommerce' ) );
								}
								$url = remove_query_arg( array(
									'sender_batch_id',
									'yith_payouts_action',
									'yith_payouts_pay_nonce'
								) );
								wp_safe_redirect( $url );
								exit;
							}
						}
						break;
					case 'update_item_status':
						if ( isset( $_REQUEST['yith_payouts_update_item_status_nonce'] ) ) {
							wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['yith_payouts_update_item_status_nonce'] ) ), 'payouts_item_update_status' );
							if ( isset( $_REQUEST['payout_item_id'] ) ) {
								$payout_item_id = sanitize_text_field( wp_unslash( $_REQUEST['payout_item_id'] ) );
								YITH_PayOuts_Service()->check_payout_item_status( $payout_item_id );
								$url = remove_query_arg( array(
									'payout_item_id',
									'yith_payouts_action',
									'yith_payouts_update_item_status_nonce'
								) );
								wp_safe_redirect( $url );
								exit;
							}
						}
						break;
				}
			}
		}

		/**
		 * Handle the receivers actions
		 *
		 * @since 2.0.0
		 */
		public function handler_receiver_actions() {

			if ( isset( $_REQUEST['yith_payouts_receiver_action'] ) ) {
				$action = sanitize_text_field( wp_unslash( $_REQUEST['yith_payouts_receiver_action'] ) );
				if ( 'delete_receiver' === $action ) {
					if ( isset( $_REQUEST['yith_payouts_delete_nonce'] ) ) {
						wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['yith_payouts_delete_nonce'] ) ), 'delete_reciever' );
						if ( isset( $_REQUEST['paypal_email'] ) ) {
							$email_to_remove = sanitize_text_field( wp_unslash( $_REQUEST['paypal_email'] ) );
							$receivers       = get_option( 'yith_payouts_receiver_list', array() );
							$new_receiver    = array();
							foreach ( $receivers as $receiver ) {
								if ( $email_to_remove !== $receiver['paypal_email'] ) {
									$new_receiver[] = $receiver;
								}
							}
							update_option( 'yith_payouts_receiver_list', $new_receiver );
							$url      = admin_url( 'admin.php' );
							$url_args = array(
								'page' => 'yith_wc_paypal_payouts_panel',
								'tab'  => 'payout-receivers',
							);
							$url      = add_query_arg( $url_args, $url );
							wp_safe_redirect( $url );
							exit;
						}
					}
				}
			}
		}

		/**
		 * Start import
		 *
		 * @return void
		 * @since 2.0.0
		 */
		private function import_start() {
			if ( function_exists( 'gc_enable' ) ) {
				gc_enable();
			}
			//phpcs:disable WordPress.PHP.NoSilencedErrors.Discouraged
			@set_time_limit( 0 );
			@ob_flush();
			@flush();
			@ini_set( 'auto_detect_line_endings', '1' );
		}

		/**
		 * Generate the Payouts from CSV file
		 *
		 * @since 2.0.0
		 */
		public function generate_payouts() {
			check_ajax_referer( 'generate-payouts', 'security' );

			if ( isset( $_FILES['file'], $_FILES['file']['tmp_name'] ) ) {
				$this->import_start();
				$file_name = $_FILES['file']['tmp_name'];// phpcs:ignore

				$delimiter = isset( $_POST['delimiter'] ) ? sanitize_text_field( wp_unslash( $_POST['delimiter'] ) ) : ',';

				if ( ( $handle = fopen( $file_name, 'r' ) ) !== false ) { //phpcs:ignore

					$header = fgetcsv( $handle, 0, $delimiter );

					$payouts_to_generate = array();
					if ( 3 === count( $header ) ) {

						while ( ( $row = fgetcsv( $handle, 0, $delimiter ) ) !== false ) { //phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition

							if ( ! is_array( $row ) || count( $row ) < 3 ) {
								continue;
							}
							list( $email, $amount, $currency ) = $row;

							$single                = array(
								'email'    => $email,
								'amount'   => $amount,
								'currency' => $currency,
							);
							$payouts_to_generate[] = $single;
						}
					}
					if ( count( $payouts_to_generate ) > 0 ) {
						$items = array();
						foreach ( $payouts_to_generate as $payout ) {
							$item    = array(
								'recipient_type' => 'EMAIL',
								'receiver'       => $payout['email'],
								'amount'         => array(
									'value'    => number_format( $payout['amount'], 2 ),
									'currency' => $payout['currency'],
								),
							);
							$items[] = $item;
						}

						$sender_batch_id = uniqid();
						$args            = array(
							'order_id'        => '',
							'payout_mode'     => 'csv',
							'sender_batch_id' => $sender_batch_id,
							'items'           => $items,
						);

						YITH_PayOuts_Service()->register_payouts( $args );

					}
				}
			}
			wp_send_json_success();
		}

		/**
		 * Download the sample csv file
		 *
		 * @since 2.0.0
		 */
		public function download_csv_file() {
			check_admin_referer( 'yith-payouts-download' );

			header( "Content-type: application/csv" );
			header( "Content-Disposition: attachment; filename=sample_payouts.csv" );
			header( "Pragma: no-cache" );
			header( "Expires: 0" );
			readfile( YITH_PAYOUTS_DIR . 'sample-data/sample_payouts.csv' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_readfile
		}
	}
}
