<?php
/**
 * Plugin Name: Paychef Payments for WooCommerce
 * Description: Securely accept a wide range of payment methods on your store with the Paychef gateway.
 * Author: Paychef
 * Author URI: https://paychef.com
 * Version: 3.0.36
 * Requires at least: 4.4
 * Tested up to: 6.8.2
 * Requires Plugins: woocommerce
 * WC requires at least: 3.8.1
 * WC tested up to: 8.1.1
 * License: GPLv2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain: paychef-payments-for-woocommerce
 * Domain Path: /languages
 */

// Exit if accessed directly
if (!defined('ABSPATH')) {
	exit();
}

// Check if woocommerce is installed
$active_plugins = get_option('active_plugins', []);
if (function_exists('is_multisite') && is_multisite()) {
	$active_plugins = array_merge(
		$active_plugins,
		get_site_option('active_sitewide_plugins', [])
	);
}

$is_woocommerce_active = in_array('woocommerce/woocommerce.php', $active_plugins) ||
                         array_key_exists('woocommerce/woocommerce.php', $active_plugins);

if (!$is_woocommerce_active) {
	return;
}

use PaychefPaymentGateway\Service\PaychefApiService;
use PaychefPaymentGateway\Service\OrderService;
use PaychefPaymentGateway\Webhook\Dispatcher;
use PaychefPaymentGateway\Helper\PaymentHelper;

if (!class_exists('PayChef_Gateway')) {
	class PayChef_Gateway
	{

		/**
		 * @var PaychefApiService
		 */
		protected $paychefApiService;

		/**
		 * @var OrderService
		 */
		protected $orderService;

		/**
		 * @var Dispatcher
		 */
		protected $webhookDispatcher;

		private $paymentMethodList = [];

		protected static $_instance = null;

		public static function instance()
		{
			if (null === self::$_instance) {
				self::$_instance = new self();
			}
			return self::$_instance;
		}

		public function __construct()
		{
			$this->define_constants();
			$this->include();
			$this->init();
			$this->register_hooks();
			foreach (scandir(PAYCHEF_PM_DIR) as $paymentMethod) {
				if (!strpos($paymentMethod, '.php')) continue;
				$this->paymentMethodList[] = str_replace('.php', '', $paymentMethod);
			}
		}

		public function paychef_get_plugin_version() {
			if (!function_exists('get_plugin_data')) {
				require_once(ABSPATH . 'wp-admin/includes/plugin.php');
			}

			$plugin_data = get_plugin_data(PAYCHEF_MAIN_FILE);
			return $plugin_data['Version'];
		}

		protected function define_constants()
		{
			define('PAYCHEF_PLUGIN_DIR', plugin_dir_path(__FILE__));
			define('PAYCHEF_PM_DIR', PAYCHEF_PLUGIN_DIR . 'src/Model/PaymentMethod/');
			define('PAYCHEF_PM_BLOCK_DIR', PAYCHEF_PLUGIN_DIR . 'src/Blocks/PaymentMethod/');
			define('PAYCHEF_MAIN_FILE', __FILE__);
			define('PAYCHEF_MAIN_NAME', plugin_basename(__FILE__));

			define('PAYCHEF_CONFIGS_PREFIX', 'paychef_configs_');
			define('PAYCHEF_PM_PREFIX', 'paychef_');

			define('PAYCHEF_ADMIN_SETTINGS_ID', 'paychef');

			define('LANG', ['en', 'de', 'it', 'fr', 'nl', 'pt', 'tr']);
		}

		protected function include()
		{
			require_once PAYCHEF_PLUGIN_DIR . '/vendor/autoload.php';
			require_once PAYCHEF_PLUGIN_DIR . '/src/Service/PaychefApiService.php';
			require_once PAYCHEF_PLUGIN_DIR . '/src/Service/OrderService.php';
			require_once PAYCHEF_PLUGIN_DIR . '/src/Helper/SubscriptionHelper.php';
			require_once PAYCHEF_PLUGIN_DIR . '/src/Helper/PaymentHelper.php';
			require_once PAYCHEF_PLUGIN_DIR . '/src/Util/BasketUtil.php';
			require_once PAYCHEF_PLUGIN_DIR . '/src/Util/StatusUtil.php';
			require_once PAYCHEF_PLUGIN_DIR . '/src/Webhook/Dispatcher.php';
			require_once PAYCHEF_PLUGIN_DIR . '/includes/settings/paychef_advanced_settings.php';

			if (is_admin()) {
				require_once PAYCHEF_PLUGIN_DIR . '/includes/admin/class-paychef-gateway-admin.php';
			}
		}

		protected function init()
		{
			if (is_admin()) {
				new PayChef_Gateway_Admin(__FILE__);
			}

			$this->paychefApiService = self::getPaychefApiService();
			$this->orderService = self::getOrderService();
			$this->webhookDispatcher = new Dispatcher($this->paychefApiService, $this->orderService, get_option(PAYCHEF_CONFIGS_PREFIX . 'prefix'));
		}

		protected function register_hooks()
		{
			add_action(
				'plugins_loaded',
				[
					$this,
					'loaded',
				]
			);

			add_action(
				'init',
				[
					$this,
					'load_textdomain',
				]
			);

			add_action(
				'woocommerce_api_wc_paychef_gateway',
				[
					$this->webhookDispatcher,
					'check_webhook_response'
				]
			);

			add_action(
				'wp_enqueue_scripts',
				[
					$this,
					'payment_scripts'
				]
			);


			add_action('wp_ajax_paychef_delete_payment_method', [$this, 'ajax_delete_payment_method']);
			add_action('wp_ajax_nopriv_paychef_delete_payment_method', [$this, 'ajax_delete_payment_method']);

			add_action('before_woocommerce_init', function () {
				if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
					\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true);
					\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_checkout_blocks', __FILE__, true);
				}
			});
		}

		/**
		 * Custom function to register a payment method type
		 */
		public function register_block_payment_methods()
		{
			// Check if the required class exists.
			if (!class_exists('Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType')) {
				return;
			}

			add_action(
				'woocommerce_blocks_payment_method_type_registration',
				function (Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry) {
					foreach ($this->paymentMethodList as $payment_method) {
						$block_gateway = 'PayChef_Gateway_' . $payment_method . '_Block';
						$payment_method_registry->register(new $block_gateway());
					}
				}
			);

		}

		public function load_textdomain()
		{
			load_plugin_textdomain('paychef-payments-for-woocommerce', false, basename(dirname(PAYCHEF_MAIN_FILE)) . '/languages');
		}

		public function loaded()
		{
			require_once PAYCHEF_PM_DIR . 'Abstract/Base.php';
			require_once PAYCHEF_PM_DIR . 'Abstract/SubscriptionBase.php';
			require_once PAYCHEF_PM_BLOCK_DIR . 'Base/class-wc-paychef-gateway-block-base.php';

			foreach ($this->paymentMethodList as $paymentMethod) {
				require_once PAYCHEF_PM_DIR . $paymentMethod . '.php';
				require_once PAYCHEF_PM_BLOCK_DIR . 'class-wc-paychef-gateway-' . strtolower($paymentMethod) . '-block.php';
			}

			// Add payment gateways
			add_filter(
				'woocommerce_payment_gateways',
				function ($gateways) {
					foreach ($this->paymentMethodList as $paymentMethod) {
						$gateways[] = 'PayChef_Gateway_' . $paymentMethod;
					}

					return $gateways;
				}
			);

			add_action(
				'woocommerce_blocks_loaded',
				[
					$this,
					'register_block_payment_methods'
				]
			);

			add_filter(
				'woocommerce_valid_order_statuses_for_payment',
				[
					$this,
					'allow_order_payment_on_cancelled'
				],
				10,
				2
			);
		}

		public function payment_scripts()
		{
			if (!is_cart() && !is_checkout() && !isset($_GET['pay_for_order']) && !is_add_payment_method_page() && !is_account_page()) {
				return;
			}

			wp_register_style('paychef_styles', plugins_url('assets/css/paychef-styles.css', PAYCHEF_MAIN_FILE));
			wp_enqueue_style('paychef_styles');

			wp_register_script('paychef_payment_methods_js', plugins_url('assets/js/paychef-payment-methods.js', PAYCHEF_MAIN_FILE), array('jquery'), '1.0.0', true);
			wp_enqueue_script('paychef_payment_methods_js');

			wp_localize_script('paychef_payment_methods_js', 'paychef_payment_methods_params', array(
				'ajax_url' => admin_url('admin-ajax.php'),
				'delete_nonce' => wp_create_nonce('paychef_delete_payment_method'),
				'confirm_delete' => __('Are you sure you want to delete this payment method?', 'paychef-payments-for-woocommerce'),
				'delete_error' => __('Error deleting payment method. Please try again.', 'paychef-payments-for-woocommerce'),
				'delete_text' => __('Delete', 'paychef-payments-for-woocommerce'),
				'no_methods_text' => __('No saved payment methods found.', 'paychef-payments-for-woocommerce'),
			));

			if (isset($_GET['paychef_error'])) {
				// Sanitize the error parameter
				$error = sanitize_text_field($_GET['paychef_error']);
				if (!empty($error)) {
					wc_add_notice(__('Payment failed. Please choose another method.', 'paychef-payments-for-woocommerce'), 'error');
					PaymentHelper::handleError();
				}
			}

			$googlePayPaymentMethod = new PayChef_Gateway_GooglePay();
			if ('yes' == $googlePayPaymentMethod->enabled) {
				wp_register_script('googlepay_js', 'https://pay.google.com/gp/p/js/pay.js', array('jquery'));
				wp_enqueue_script('googlepay_js');
				wp_register_script('paychef_googlepay_check', plugins_url('assets/js/googlepay.js', PAYCHEF_MAIN_FILE), array(), '1.0.1', true);
				wp_enqueue_script('paychef_googlepay_check');
			}

			$applePayPaymentMethod = new PayChef_Gateway_ApplePay();
			if ('yes' == $applePayPaymentMethod->enabled) {
				wp_register_script('paychef_applepay_check', plugins_url('assets/js/applepay.js', PAYCHEF_MAIN_FILE), array(), '1.0.1', true);
				wp_enqueue_script('paychef_applepay_check');
			}
		}

        /**
         * @param WC_Order|null $order
         * @return PaychefApiService
         */
		public static function getPaychefApiService(WC_Order $order = null): PaychefApiService
		{
			$instance = get_option(PAYCHEF_CONFIGS_PREFIX . 'instance');
			$api_key = get_option(PAYCHEF_CONFIGS_PREFIX . 'api_key');
			$platform = get_option(PAYCHEF_CONFIGS_PREFIX . 'platform');
			$look_and_feel_id = get_option(PAYCHEF_CONFIGS_PREFIX . 'look_and_feel_id');

			// Überprüfen Sie, ob Multistore aktiv ist und passen Sie die Werte entsprechend an
			if (class_exists('Lieferchef_Stores') && Lieferchef_Stores::is_multistore()) {
                $store = null;

                if (!is_null($order)) {
                    $shopId = $order->get_meta('lieferchef_shop_id');
                    if (!empty($shopId)) {
                        $store = Lieferchef_Stores::get_store($shopId);
                    }
                }

                if (!$store) {
                    $store = Lieferchef_Stores::get_current_store();
                }

				if ($store && is_object($store)) {
					$api_key = sanitize_text_field($store->paychef_sid);
					$instance = sanitize_text_field($store->paychef_instance);
				}
			}

			return new PaychefApiService(
				$instance,
				$api_key,
				$platform,
				$look_and_feel_id
			);
		}

		public static function getOrderService()
		{
			return new OrderService();
		}

		/**
		 * Allow payment retry for cancelled orders when using Paychef payment methods.
		 *
		 * @param array    $statuses Valid order statuses for payment.
		 * @param WC_Order $order    The WooCommerce order object.
		 * @return array
		 */
		public function allow_order_payment_on_cancelled(array $statuses, WC_Order $order): array {
			if (
				strpos($order->get_payment_method(), 'paychef') === 0 &&
				$order->has_status(OrderService::WC_STATUS_CANCELLED)
			) {
				$statuses[] = OrderService::WC_STATUS_CANCELLED;
			}

			return $statuses;
		}


		/**
		 * AJAX handler for deleting payment methods
		 */
		public function ajax_delete_payment_method() {
			if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['security'])), 'paychef_delete_payment_method')) {
				wp_die(__('Security check failed', 'paychef-payments-for-woocommerce'));
			}

			if (!is_user_logged_in()) {
				wp_send_json_error(__('You must be logged in to delete payment methods.', 'paychef-payments-for-woocommerce'));
			}

			$token_id = absint($_POST['token_id']);
			$token = WC_Payment_Tokens::get($token_id);

			if (!$token || $token->get_user_id() !== get_current_user_id()) {
				wp_send_json_error(__('Invalid payment method.', 'paychef-payments-for-woocommerce'));
			}

			if (!$token->get_gateway_id() || strpos($token->get_gateway_id(), 'paychef') !== 0) {
				wp_send_json_error(__('This payment method cannot be deleted.', 'paychef-payments-for-woocommerce'));
			}

			if (WC_Payment_Tokens::delete($token_id)) {
				wp_send_json_success(__('Payment method deleted successfully.', 'paychef-payments-for-woocommerce'));
			} else {
				wp_send_json_error(__('Failed to delete payment method.', 'paychef-payments-for-woocommerce'));
			}
		}
	}
}

PayChef_Gateway::instance();
