<?php

namespace Dobare\Admin\API\Dashboard;

use Dobare\Abstracts\Dobare_REST_Controller;
use Dobare\Utils\Dobare_Utils;
use Dobare\Abandoned_Cart\Dobare_Abandoned_Cart_Guard;
use Dobare\Abandoned_Cart\Dobare_Abandoned_Cart_Service;
use Dobare\Lead_Magnet\Dobare_Lead_Magnet_Service;
use Dobare\Customer_Credit\Dobare_Customer_Credit_Service;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;

class Dobare_Dashboard_REST_Controller extends Dobare_REST_Controller
{
	protected $dobare_api_key_header_name;
	protected $dobare_cashback_uri;
	protected $dobare_credit_expiry_reminder_uri;
	protected $dobare_self_uri;
	protected $dobare_packages_uri;
	protected $dobare_payment_link_uri;
	protected $dobare_lead_magnet_uri;
	protected $dobare_sync_customers_uri;
	protected $cashback_route;
	protected $credit_reminder_route;
	protected $self_route;
	protected $api_key_route;
	protected $packages_route;
	protected $payment_link_route;
	protected $sync_order_status_route;
	protected $lead_magnet_route;
	protected $sync_customers_route;
	protected $customer_credit_route;
	protected $credit_with_discount_route;
	protected $minimum_cart_total_route;
	protected $logout_route;
	protected $lead_magnet_compatibility_route;
	protected $abandoned_cart_route;
	protected $abandoned_cart_logs_route;
	protected $abandoned_cart_logs_purge_route;
	protected $credit_disable_window_route;
	protected $custom_lead_magnet_route;
	protected $custom_lead_magnet_preview_route;

	public function __construct()
	{
		$this->resource_name                     = 'dashboard';
		$this->dobare_api_key_header_name        = 'API-KEY';
		$this->dobare_cashback_uri               = 'v1/integrations/cashback/';
		$this->dobare_credit_expiry_reminder_uri = 'v1/integrations/reminder/';
		$this->dobare_self_uri                   = 'v1/integrations/self/';
		$this->dobare_packages_uri               = 'v1/integrations/wp/plugin-packages/';
		$this->dobare_payment_link_uri           = 'v1/integrations/wp/payment-link/';
		$this->dobare_lead_magnet_uri 			 = 'v1/integrations/wp/lead-magnet/';
		$this->dobare_sync_customers_uri         = 'v1/integrations/wp/sync-customers/';
		$this->cashback_route                    = '/cashback';
		$this->credit_reminder_route             = '/credit-expiry-reminder';
		$this->self_route                        = '/self';
		$this->api_key_route                     = '/api-key';
		$this->packages_route                    = '/packages';
		$this->payment_link_route                = '/payment-link';
		$this->sync_order_status_route           = '/sync-order-status';
		$this->lead_magnet_route 				 = '/lead-magnet';
		$this->sync_customers_route              = '/sync-customers';
		$this->customer_credit_route             = '/customer-credit';
		$this->credit_with_discount_route        = '/credit-with-discount';
		$this->minimum_cart_total_route          = '/minimum-cart-total';
		$this->logout_route                      = '/logout';
		$this->lead_magnet_compatibility_route   = '/lead-magnet-compatibility';
		$this->abandoned_cart_route              = '/abandoned-cart';
		$this->abandoned_cart_logs_route         = '/abandoned-cart/logs';
		$this->abandoned_cart_logs_purge_route   = '/abandoned-cart/logs/purge';
		$this->credit_disable_window_route       = '/credit-disable-window';
		$this->custom_lead_magnet_route          = '/custom-lead-magnet';
		$this->custom_lead_magnet_preview_route  = '/custom-lead-magnet/preview';
	}


	public function register_routes()
	{
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->cashback_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'create_cashback'),
			'permission_callback' => array($this, 'dashboard_permissions_check'),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->cashback_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_cashback'),
			'permission_callback' => array($this, 'dashboard_permissions_check'),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->credit_reminder_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'create_reminder'),
			'permission_callback' => array($this, 'dashboard_permissions_check'),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->credit_reminder_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_reminder'),
			'permission_callback' => array($this, 'dashboard_permissions_check'),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->api_key_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_api_key'),
			'permission_callback' => array($this, 'dashboard_permissions_check_api_key'),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->api_key_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'set_api_key'),
			'permission_callback' => array($this, 'dashboard_permissions_check_api_key'),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->self_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_self'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->payment_link_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'get_payment_link'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->packages_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_packages'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->sync_order_status_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_sync_order_status'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->sync_order_status_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'set_sync_order_status'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->lead_magnet_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_lead_magnet'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->lead_magnet_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'create_lead_magnet'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->sync_customers_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'sync_customers'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->sync_customers_route . '/progress', array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_sync_customers_progress'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->sync_customers_route . '/reset', array(
			'methods'             => 'POST',
			'callback'            => array($this, 'reset_sync_customers'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->customer_credit_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_customer_credit_settings'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->customer_credit_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'update_customer_credit_settings'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->credit_with_discount_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_credit_with_discount_settings'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->credit_with_discount_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'update_credit_with_discount_settings'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->minimum_cart_total_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_minimum_cart_total_settings'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->minimum_cart_total_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'update_minimum_cart_total_settings'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->abandoned_cart_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_abandoned_cart_settings'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->abandoned_cart_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'update_abandoned_cart_settings'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->abandoned_cart_logs_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_abandoned_cart_logs'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->abandoned_cart_logs_purge_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'purge_abandoned_cart_logs'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->credit_disable_window_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_credit_disable_window'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->credit_disable_window_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'update_credit_disable_window'),
			'permission_callback' => array(
				$this,
				'dashboard_permissions_check'
			),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->logout_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'logout'),
			'permission_callback' => array($this, 'dashboard_permissions_check_api_key'),
		));

		// Lead magnet compatibility flag
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->lead_magnet_compatibility_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_lead_magnet_compatibility_setting'),
			'permission_callback' => array($this, 'dashboard_permissions_check'),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->lead_magnet_compatibility_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'update_lead_magnet_compatibility_setting'),
			'permission_callback' => array($this, 'dashboard_permissions_check'),
		));

		// Custom lead magnet HTML/CSS
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->custom_lead_magnet_route, array(
			'methods'             => 'GET',
			'callback'            => array($this, 'get_custom_lead_magnet'),
			'permission_callback' => array($this, 'dashboard_permissions_check'),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->custom_lead_magnet_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'update_custom_lead_magnet'),
			'permission_callback' => array($this, 'dashboard_permissions_check'),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->custom_lead_magnet_route, array(
			'methods'             => 'DELETE',
			'callback'            => array($this, 'reset_custom_lead_magnet'),
			'permission_callback' => array($this, 'dashboard_permissions_check'),
		));
		\register_rest_route($this->namespace, '/' . $this->resource_name . $this->custom_lead_magnet_preview_route, array(
			'methods'             => 'POST',
			'callback'            => array($this, 'preview_custom_lead_magnet'),
			'permission_callback' => array($this, 'dashboard_permissions_check'),
		));
	}

	public function dashboard_permissions_check(WP_REST_Request $request)
	{
		// Verify nonce for CSRF protection
		// WordPress REST API automatically handles nonce verification for logged-in users
		// via the X-WP-Nonce header, but we add explicit check for extra security
		if (! wp_verify_nonce($request->get_header('X-WP-Nonce'), 'wp_rest')) {
			// For cookie-based authentication, nonce is required
			if (! is_user_logged_in()) {
				return new WP_Error(
					'rest_forbidden',
					esc_html__('Invalid security token.', 'dobare'),
					array('status' => 403)
				);
			}
		}

		if (! current_user_can('manage_options')) {
			return new WP_Error(
				'permission_denied',
				esc_html__('You cannot view the post resource.', 'dobare'),
				array('status' => $this->dobare_authorization_status_code())
			);
		}
		if (empty(Dobare_Utils::get_dob_api_key())) {
			return new WP_Error(
				'permission_denied',
				esc_html__('Please create your business first and set the api key', 'dobare'),
				array('status' => $this->dobare_authorization_status_code())
			);
		}

		return true;
	}

	public function dashboard_permissions_check_api_key(WP_REST_Request $request)
	{
		// Verify nonce for CSRF protection
		if (! wp_verify_nonce($request->get_header('X-WP-Nonce'), 'wp_rest')) {
			if (! is_user_logged_in()) {
				return new WP_Error(
					'rest_forbidden',
					esc_html__('Invalid security token.', 'dobare'),
					array('status' => 403)
				);
			}
		}

		if (! current_user_can('manage_options')) {
			return new WP_Error(
				'permission_denied',
				esc_html__('You cannot view the post resource.', 'dobare'),
				array('status' => $this->dobare_authorization_status_code())
			);
		}

		return true;
	}

	public function get_self(WP_REST_Request $request)
	{
		$response = self::dobare_remote_get($this->dobare_self_uri, $this->get_dob_request_headers());

		return is_wp_error($response) ? $response : new WP_REST_Response($response["data"], $response["status"]);
	}

	public function get_dob_request_headers(): array
	{
		return array($this->dobare_api_key_header_name => Dobare_Utils::get_dob_api_key());
	}

	public function get_cashback(WP_REST_Request $request)
	{
		$response = self::dobare_remote_get($this->dobare_cashback_uri, $this->get_dob_request_headers());

		return is_wp_error($response) ? $response : new WP_REST_Response($response["data"], $response["status"]);
	}

	public function create_cashback(WP_REST_Request $request)
	{
		$params   = $request->get_json_params();
		// Sanitize integer inputs using absint for non-negative integers
		$percent  = isset($params['percent']) ? absint($params['percent']) : null;
		$maximum  = isset($params['maximum']) ? absint($params['maximum']) : null;
		$duration = isset($params['duration']) ? absint($params['duration']) : null;
		$delay    = isset($params['delay']) ? absint($params['delay']) : null;
		$body     = array(
			'percent'  => $percent,
			'maximum'  => $maximum,
			'duration' => $duration,
			'delay'    => $delay,
		);
		$response = self::dobare_remote_post($this->dobare_cashback_uri, $body, $this->get_dob_request_headers());

		return is_wp_error($response) ? $response : new WP_REST_Response($response["data"], $response["status"]);
	}

	public function get_reminder(WP_REST_Request $request)
	{
		$response = self::dobare_remote_get($this->dobare_credit_expiry_reminder_uri, $this->get_dob_request_headers());

		return is_wp_error($response) ? $response : new WP_REST_Response($response["data"], $response["status"]);
	}

	public function create_reminder(WP_REST_Request $request)
	{
		$params              = $request->get_json_params();
		// Sanitize integer and text inputs
		$days_left_to_expire = isset($params['days_left_to_expire']) ? absint($params['days_left_to_expire']) : null;
		$time_to_execute     = isset($params['time_to_execute']) ? sanitize_text_field($params['time_to_execute']) : null;
		$body                = array(
			'days_left_to_expire' => $days_left_to_expire,
			'time_to_execute'     => $time_to_execute,
		);
		$response            = self::dobare_remote_post($this->dobare_credit_expiry_reminder_uri, $body, $this->get_dob_request_headers());

		return is_wp_error($response) ? $response : new WP_REST_Response($response["data"], $response["status"]);
	}

	public function get_api_key(WP_REST_Request $request): WP_REST_Response
	{
		$api_key             = Dobare_Utils::get_dob_api_key();
		$body                = array(
			'api_key' => $api_key ?? '',
		);
		$normalized_response = Dobare_Utils::normalize_response_body($body, 200);

		return new WP_REST_Response($normalized_response, 200);
	}

	public function set_api_key(WP_REST_Request $request)
	{
		$params  = $request->get_json_params();
		// Sanitize API key - remove any whitespace and special characters except hyphens
		$api_key = isset($params['api_key']) ? sanitize_text_field($params['api_key']) : '';

		// Validate API key format
		if (!is_string($api_key) || strlen($api_key) !== 36) {
			return new WP_REST_Response(
				Dobare_Utils::normalize_error_body(array('فرمت کلید API نامعتبر است. کلید API باید ۳۶ کاراکتر باشد.'), 400),
				400
			);
		}

		// Validate API key with remote server
		$response = self::dobare_remote_get('v1/integrations/self/', array('API-KEY' => $api_key));

		if (is_wp_error($response)) {
			return new WP_REST_Response(
				Dobare_Utils::normalize_error_body(array('خطا در اتصال به سرور. لطفاً دوباره تلاش کنید.'), 500),
				500
			);
		}

		$status = $response["status"];

		if ($status === 200) {
			// API key is valid, save it
			Dobare_Utils::set_dob_api_key($api_key);
			$body = array('api_key' => $api_key);
			$normalized_response = Dobare_Utils::normalize_response_body($body, 200);
			return new WP_REST_Response($normalized_response, 200);
		} else {
			// Handle different error statuses
			$error_messages = array();

			switch ($status) {
				case 401:
				case 403:
					$error_messages = array('کلید API نامعتبر است. لطفاً کلید صحیح را وارد کنید.');
					break;
				case 404:
					$error_messages = array('کلید API یافت نشد. لطفاً از صحت کلید اطمینان حاصل کنید.');
					break;
				default:
					// Try to extract error messages from response
					if (isset($response['data']['meta']['detail']['global_error_messages'])) {
						$error_messages = $response['data']['meta']['detail']['global_error_messages'];
					} else {
						$error_messages = array('خطایی در اعتبارسنجی کلید API رخ داده است. لطفاً دوباره تلاش کنید.');
					}
					break;
			}

			return new WP_REST_Response(
				Dobare_Utils::normalize_error_body($error_messages, $status),
				$status
			);
		}
	}

	public function get_packages(WP_REST_Request $request): WP_REST_Response
	{
		$response = self::dobare_remote_get($this->dobare_packages_uri, $this->get_dob_request_headers());

		return is_wp_error($response) ? $response : new WP_REST_Response($response["data"], $response["status"]);
	}

	public function get_payment_link(WP_REST_Request $request)
	{
		$params   = $request->get_json_params();
		// Sanitize text inputs
		$duration = isset($params['duration']) ? sanitize_text_field($params['duration']) : null;
		$title    = isset($params['title']) ? sanitize_text_field($params['title']) : null;
		$body     = array("subscription_duration" => $duration, 'title' => $title);
		$response = self::dobare_remote_post($this->dobare_payment_link_uri, $body, $this->get_dob_request_headers());

		return is_wp_error($response) ? $response : new WP_REST_Response($response["data"], $response["status"]);
	}

	public function get_sync_order_status(WP_REST_Request $request)
	{
		$order_statuses       = wc_get_order_statuses();
		$current_active_value = Dobare_Utils::get_sync_order_status();
		$response_body        = array(
			"current_active_value" => array('label' => '', 'value' => $current_active_value),
			'available_statuses'   => array()
		);
		foreach ($order_statuses as $status_key => $status_label) {
			$status_key = str_starts_with($status_key, 'wc-') ? substr($status_key, 3) : $status_key;
			$response_body['available_statuses'][] = array(
				'label' => $status_label,
				'value' => $status_key,
			);

			if ($status_key == $current_active_value) {
				$response_body['current_active_value']['label'] = $status_label;
			}
		}
		$response = Dobare_Utils::normalize_response_body($response_body, 200);

		return is_wp_error($response) ? $response : new WP_REST_Response($response, $response["status"]);
	}

	public function set_sync_order_status(WP_REST_Request $request)
	{
		$params       = $request->get_json_params();
		// Sanitize order status input
		$order_status = isset($params['order_status']) ? sanitize_key($params['order_status']) : null;
		$normalized_order_status = str_starts_with($order_status, 'wc-') ? substr($order_status, 3) : $order_status;
		$status       = 400;
		if (! empty($order_status)) {
			Dobare_Utils::set_sync_order_status($normalized_order_status);
			$status = 200;
		}
		$success       = $status === 200;
		$response_body = array(
			"success" => $success
		);
		$response      = Dobare_Utils::normalize_response_body($response_body, $status);

		return is_wp_error($response) ? $response : new WP_REST_Response($response, $response["status"]);
	}

	public function get_lead_magnet(WP_REST_Request $request)
	{
		if (
			! Dobare_Utils::is_lead_magnet_without_login_plugin_enabled() &&
			! function_exists('digits_version') &&
			! Dobare_Lead_Magnet_Service::is_mobits_active() &&
			! Dobare_Lead_Magnet_Service::is_kerasno_sms_active() &&
			! Dobare_Lead_Magnet_Service::is_voorodak_active()
		) {
			$response_body = Dobare_Utils::normalize_error_body(array('برای استفاده از قابلیت لید مگنت، به فعال بودن یکی از افزونه های ورود سازگار دارید نیاز دارید (دیجیتس - کراسنو - موبیتس - ورودک)',), 400);

			return new WP_REST_Response($response_body, 400);
		}
		$response = self::dobare_remote_get($this->dobare_lead_magnet_uri, $this->get_dob_request_headers());

		return is_wp_error($response) ? $response : new WP_REST_Response($response["data"], $response["status"]);
	}

	public function create_lead_magnet(WP_REST_Request $request)
	{
		if (
			! Dobare_Utils::is_lead_magnet_without_login_plugin_enabled() &&
			! function_exists('digits_version') &&
			! Dobare_Lead_Magnet_Service::is_mobits_active() &&
			! Dobare_Lead_Magnet_Service::is_kerasno_sms_active() &&
			! Dobare_Lead_Magnet_Service::is_voorodak_active()
		) {
			$response_body = Dobare_Utils::normalize_error_body(array('برای استفاده از قابلیت لید مگنت، به فعال بودن یکی از افزونه های ورود سازگار دارید نیاز دارید (دیجیتس - کراسنو - موبیتس - ورودک)',), 400);

			return new WP_REST_Response($response_body, 400);
		}
		$params         = $request->get_json_params();
		// Sanitize inputs
		$expire_in_days = isset($params['expire_in_days']) ? absint($params['expire_in_days']) : null;
		$position       = isset($params['position']) ? sanitize_text_field($params['position']) : null;
		$credit_amount  = isset($params['credit_amount']) ? absint($params['credit_amount']) : null;
		$body           = array(
			'expire_in_days' => $expire_in_days,
			'position'       => $position,
			'credit_amount'  => $credit_amount,
		);
		$response       = self::dobare_remote_post($this->dobare_lead_magnet_uri, $body, $this->get_dob_request_headers());

		return is_wp_error($response) ? $response : new WP_REST_Response($response["data"], $response["status"]);
	}

	/**
	 * Get Lead Magnet compatibility setting (allow without login plugin)
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function get_lead_magnet_compatibility_setting(WP_REST_Request $request)
	{
		$settings = array(
			'is_enabled' => Dobare_Utils::is_lead_magnet_without_login_plugin_enabled()
		);

		$normalized_response = Dobare_Utils::normalize_response_body($settings, 200);
		return new WP_REST_Response($normalized_response, 200);
	}

	/**
	 * Update Lead Magnet compatibility setting (allow without login plugin)
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function update_lead_magnet_compatibility_setting(WP_REST_Request $request)
	{
		$params = $request->get_json_params();
		$is_enabled = isset($params['is_enabled']) ? (bool) $params['is_enabled'] : false;

		$success = Dobare_Utils::set_lead_magnet_without_login_plugin_enabled($is_enabled);

		if ($success) {
			$settings = array(
				'is_enabled' => $is_enabled,
				'message' => $is_enabled ? 'نمایش لید مگنت بدون افزونه ورود سازگار فعال شد' : 'نمایش لید مگنت بدون افزونه ورود سازگار غیرفعال شد'
			);
			$normalized_response = Dobare_Utils::normalize_response_body($settings, 200);
			return new WP_REST_Response($normalized_response, 200);
		} else {
			$error_response = Dobare_Utils::normalize_error_body(array('خطا در به‌روزرسانی تنظیمات'), 500);
			return new WP_REST_Response($error_response, 500);
		}
	}

	/**
	 * Handle the sync customers request.
	 *
	 * @param WP_REST_Request $request The request object.
	 * @return WP_REST_Response The response.
	 */
	public function sync_customers($request)
	{
		// Get current progress to check if a sync is already running
		$current_progress = \Dobare\Utils\Dobare_Utils::get_sync_customers_progress();

		// Determine if we have a stale process
		$is_stale = false;

		// Check if the process is stale based on status and time
		if ($current_progress['status'] === 'local_processing' || $current_progress['status'] === 'remote_processing') {
			$updated_at = strtotime($current_progress['updated_at']);
			$time_elapsed = time() - $updated_at;

			if ($time_elapsed > 900) { // 15 minutes with no updates
				$is_stale = true;
				\error_log('Dobare sync: Stale process detected - no progress update for ' . round($time_elapsed / 60) . ' minutes');
			}

			// Check if progress is stuck at 0%
			if ($current_progress['progress'] === 0 && $time_elapsed > 120) { // 2 minutes
				$is_stale = true;
				\error_log('Dobare sync: Stale process detected - stuck at 0% for 2+ minutes');
			}

			// Check for a very old process (more than 1 hour)
			if ($time_elapsed > 3600) {
				$is_stale = true;
				\error_log('Dobare sync: Stale process detected - process running for over 60 minutes');
			}
		}

		// If a process is running and not stale, return error
		if (!$is_stale && ($current_progress['status'] === 'local_processing' || $current_progress['status'] === 'remote_processing')) {
			$response_body = array(
				"success" => false,
				"message" => __("فرآیند همگام‌سازی در حال حاضر در حال اجراست", 'dobare'),
				"progress" => $current_progress
			);
			$response = \Dobare\Utils\Dobare_Utils::normalize_response_body($response_body, 409);
			return new WP_REST_Response($response, 409);
		}

		// Reset progress and start a new sync process
		\Dobare\Utils\Dobare_Utils::reset_sync_customers_progress();
		\error_log('Dobare sync: New sync process started at ' . date('Y-m-d H:i:s') . ($is_stale ? ' (replaced stale process)' : ''));

		try {
			// Set initial progress
			\Dobare\Utils\Dobare_Utils::set_sync_customers_progress(
				'local_processing',
				0,
				0,
				null,
				__('در حال استخراج اطلاعات مشتریان...', 'dobare')
			);

			// Step 1: Direct SQL query to get unique customers with latest orders
			global $wpdb;

			// Update progress
			\Dobare\Utils\Dobare_Utils::set_sync_customers_progress(
				'local_processing',
				10,
				0,
				null,
				__('در حال استخراج اطلاعات مشتریان از دیتابیس...', 'dobare')
			);

			// Query to get unique customers by billing phone with their latest first/last name
			// This gets unique billing phones and the latest order data for each phone
			$query = "
				SELECT p1.post_id, p1.meta_value AS billing_phone,
				       MAX(p1.post_id) AS latest_order_id
				FROM {$wpdb->postmeta} p1
				INNER JOIN {$wpdb->posts} o ON p1.post_id = o.ID
				WHERE p1.meta_key = '_billing_phone'
				AND o.post_type = 'shop_order'
				GROUP BY p1.meta_value
				ORDER BY latest_order_id DESC
			";

			$unique_customer_orders = $wpdb->get_results($query);
			$total_customers = count($unique_customer_orders);

			// Update progress
			\Dobare\Utils\Dobare_Utils::set_sync_customers_progress(
				'local_processing',
				30,
				0,
				null,
				sprintf(__('یافتن %d مشتری منحصر به فرد با شماره تلفن...', 'dobare'), $total_customers)
			);

			// Create a temporary file to store customer data
			$temp_file = tmpfile();
			$temp_file_path = stream_get_meta_data($temp_file)['uri'];

			// Write CSV header - Make sure column order matches what backend expects
			fputcsv($temp_file, ['first_name', 'last_name', 'phone']);

			// Process each unique customer and get their details
			$processed = 0;
			$batch_size = 100; // Process in smaller batches
			$customer_batches = array_chunk($unique_customer_orders, $batch_size);

			foreach ($customer_batches as $batch_index => $batch) {
				$order_ids = array_map(function ($item) {
					return $item->latest_order_id;
				}, $batch);

				$order_ids_string = implode(',', $order_ids);

				// Get first and last names for these orders
				$name_query = "
					SELECT post_id,
						MAX(CASE WHEN meta_key = '_billing_first_name' THEN meta_value ELSE '' END) AS first_name,
						MAX(CASE WHEN meta_key = '_billing_last_name' THEN meta_value ELSE '' END) AS last_name,
						MAX(CASE WHEN meta_key = '_billing_phone' THEN meta_value ELSE '' END) AS phone
					FROM {$wpdb->postmeta}
					WHERE post_id IN ({$order_ids_string})
					AND meta_key IN ('_billing_first_name', '_billing_last_name', '_billing_phone')
					GROUP BY post_id
				";

				$customer_details = $wpdb->get_results($name_query);
				$customer_details_map = [];

				foreach ($customer_details as $detail) {
					$customer_details_map[$detail->post_id] = $detail;
				}

				foreach ($batch as $customer) {
					$order_id = $customer->latest_order_id;
					if (isset($customer_details_map[$order_id])) {
						$details = $customer_details_map[$order_id];
						// Normalize the phone number by removing any non-digit characters
						$phone = preg_replace('/[^0-9]/', '', $details->phone);

						// Only include records with valid phone numbers
						if (!empty($phone)) {
							// Write to CSV with correct column order: first_name, last_name, phone
							fputcsv($temp_file, [
								$details->first_name,
								$details->last_name,
								$phone
							]);
						}
					}
					$processed++;
				}

				// Update progress
				$progress_percentage = 30 + (50 * ($processed / $total_customers));
				\Dobare\Utils\Dobare_Utils::set_sync_customers_progress(
					'local_processing',
					min(80, (int)$progress_percentage),
					0,
					null,
					sprintf(__('پردازش مشتری %d از %d...', 'dobare'), $processed, $total_customers)
				);
			}

			// Reset file pointer to beginning for reading
			rewind($temp_file);

			// Update progress before sending to remote
			\Dobare\Utils\Dobare_Utils::set_sync_customers_progress(
				'local_processing',
				90,
				0,
				null,
				__('آماده‌سازی فایل برای ارسال به سرور...', 'dobare')
			);

			// Prepare file for upload to Dobare API
			$file_content = file_get_contents($temp_file_path);

			// Close and delete temp file
			fclose($temp_file);

			// Only proceed if we have customer data
			if ($total_customers > 0) {
				// Send data to Dobare API
				$api_key = \Dobare\Utils\Dobare_Utils::get_dob_api_key();

				// Create a unique file name
				$file_name = 'customers_sync_' . date('Ymd_His') . '.csv';

				// Prepare the file for upload using cURL
				$curl = curl_init();

				// Get the API URL - using direct URL instead of the undefined method
				// Replace the call to the undefined method with the base URL construction
				$url = rtrim(defined('DOBARE_API_URL') ? DOBARE_API_URL : 'https://api.dobare.me', '/') . '/' . $this->dobare_sync_customers_uri;

				// Create a CURLFile object
				$temp_file_for_curl = tmpfile();
				fwrite($temp_file_for_curl, $file_content);
				$temp_file_meta = stream_get_meta_data($temp_file_for_curl);
				$curl_file = new \CURLFile($temp_file_meta['uri'], 'text/csv', $file_name);

				// Parse the URL to get the hostname for SNI
				$url_parts = parse_url($url);
				$hostname = isset($url_parts['host']) ? $url_parts['host'] : 'api.dobare.me';

				// Set cURL options
				curl_setopt_array($curl, array(
					CURLOPT_URL => $url,
					CURLOPT_RETURNTRANSFER => true,
					CURLOPT_ENCODING => '',
					CURLOPT_MAXREDIRS => 10,
					CURLOPT_TIMEOUT => 180,
					CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
					CURLOPT_CUSTOMREQUEST => 'POST',
					CURLOPT_POSTFIELDS => array(
						'csv_file' => $curl_file,
					),
					CURLOPT_HTTPHEADER => array(
						'API-KEY: ' . $api_key,
						'Accept: application/json',
						'Host: ' . $hostname,
					),
					// SSL options to fix the "unrecognized name" error
					CURLOPT_SSL_VERIFYHOST => 2,  // Verify the hostname in the certificate
					CURLOPT_SSL_VERIFYPEER => true,  // Enable certificate verification
					CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2,
					CURLOPT_CONNECTTIMEOUT => 30,
				));

				// Execute request
				\Dobare\Utils\Dobare_Utils::set_sync_customers_progress(
					'local_processing',
					95,
					0,
					null,
					__('در حال ارسال اطلاعات به سرور...', 'dobare')
				);

				$api_response = curl_exec($curl);
				$err = curl_error($curl);
				$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);

				// Close cURL resources
				curl_close($curl);
				fclose($temp_file_for_curl);

				if ($err) {
					throw new \Exception("cURL Error: " . $err);
				}

				// Process API response
				$api_response_data = json_decode($api_response, true);

				if ($http_code >= 200 && $http_code < 300 && isset($api_response_data['data']['id'])) {
					// Get remote ID
					$remote_id = $api_response_data['data']['id'];

					// Update progress to remote processing
					\Dobare\Utils\Dobare_Utils::set_sync_customers_progress(
						'remote_processing',
						100,
						0,
						$remote_id,
						__('اطلاعات با موفقیت ارسال شد. در حال پردازش توسط سرور...', 'dobare')
					);

					// Immediately check remote status
					\Dobare\Utils\Dobare_Utils::check_remote_sync_status();

					// Return updated progress
					$response_body = array(
						"success" => true,
						"message" => __("اطلاعات مشتریان با موفقیت ارسال شد و در حال پردازش است", 'dobare'),
						"progress" => \Dobare\Utils\Dobare_Utils::get_sync_customers_progress()
					);
				} else {
					// Handle API error
					$error_message = isset($api_response_data['message']) ? $api_response_data['message'] : "خطا در ارسال اطلاعات به سرور";
					throw new \Exception($error_message);
				}
			} else {
				// No customers found
				\Dobare\Utils\Dobare_Utils::set_sync_customers_progress(
					'completed',
					100,
					0,
					0,
					__('هیچ مشتری با شماره تلفن معتبر یافت نشد.', 'dobare')
				);

				$response_body = array(
					"success" => true,
					"message" => __("هیچ مشتری با شماره تلفن معتبر یافت نشد.", 'dobare'),
					"progress" => \Dobare\Utils\Dobare_Utils::get_sync_customers_progress()
				);
			}
		} catch (\Exception $e) {
			\error_log('Dobare sync exception: ' . $e->getMessage());

			\Dobare\Utils\Dobare_Utils::set_sync_customers_progress(
				'error',
				0,
				0,
				null,
				__('خطای سیستمی: ', 'dobare') . $e->getMessage()
			);

			$response_body = array(
				"success" => false,
				"message" => __("همگام‌سازی با خطای سیستمی مواجه شد: ", 'dobare') . $e->getMessage(),
				"progress" => \Dobare\Utils\Dobare_Utils::get_sync_customers_progress()
			);
		}

		$response = \Dobare\Utils\Dobare_Utils::normalize_response_body($response_body, $response_body['success'] ? 200 : 500);
		return new WP_REST_Response($response, $response_body['success'] ? 200 : 500);
	}

	/**
	 * Get the current sync customers progress.
	 * This will also check the remote status if in remote processing phase.
	 *
	 * @param WP_REST_Request $request The request object.
	 * @return WP_REST_Response The response.
	 */
	public function get_sync_customers_progress(WP_REST_Request $request)
	{
		// Get progress data directly from option
		$progress = \Dobare\Utils\Dobare_Utils::get_sync_customers_progress();

		// Check remote status only if needed, avoiding unnecessary API calls
		if ($progress['status'] === 'remote_processing' && !empty($progress['remote_id'])) {
			\Dobare\Utils\Dobare_Utils::check_remote_sync_status();
			// Get the updated progress
			$progress = \Dobare\Utils\Dobare_Utils::get_sync_customers_progress();
		}

		// Create a minimal response with only necessary data
		$response_body = array(
			"success" => true,
			"progress" => $progress
		);

		$response = \Dobare\Utils\Dobare_Utils::normalize_response_body($response_body, 200);

		return new WP_REST_Response($response, 200);
	}

	/**
	 * Resets the sync customers progress and stops any scheduled events.
	 *
	 * @param WP_REST_Request $request The request object.
	 * @return WP_REST_Response The response.
	 */
	public function reset_sync_customers(WP_REST_Request $request)
	{
		// Get only the minimum data we need for reset logic
		$progress = \Dobare\Utils\Dobare_Utils::get_sync_customers_progress();
		$remote_id = isset($progress['remote_id']) ? $progress['remote_id'] : null;
		$status = isset($progress['status']) ? $progress['status'] : '';

		// Free memory early
		unset($progress);

		// If we have a remote ID and the sync is in a state where it should be marked complete, do so
		if (
			!empty($remote_id) &&
			($status === 'completed' || $status === 'remote_processing')
		) {
			// Try to mark it as complete on Dobare backend
			$marked_complete = \Dobare\Utils\Dobare_Utils::mark_sync_complete_on_dobare($remote_id);
			\error_log('Dobare sync: Marked as complete on backend: ' . ($marked_complete ? 'success' : 'failed'));
		}

		// Free memory
		unset($remote_id);
		unset($status);

		// Reset progress
		\Dobare\Utils\Dobare_Utils::reset_sync_customers_progress();

		// Simple response with minimal data
		$response_body = array(
			"success" => true,
			"message" => __("فرآیند همگام‌سازی مشتریان بازنشانی شد", 'dobare')
		);
		$response = \Dobare\Utils\Dobare_Utils::normalize_response_body($response_body, 200);

		return new WP_REST_Response($response, 200);
	}

	/**
	 * Get customer credit indicator settings
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function get_customer_credit_settings(WP_REST_Request $request)
	{
		$settings = array(
			'is_enabled' => Dobare_Customer_Credit_Service::is_feature_enabled(),
			'position'   => Dobare_Customer_Credit_Service::get_position()
		);

		$normalized_response = Dobare_Utils::normalize_response_body($settings, 200);
		return new WP_REST_Response($normalized_response, 200);
	}

	/**
	 * Update customer credit indicator settings
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function update_customer_credit_settings(WP_REST_Request $request)
	{
		$params = $request->get_json_params();
		$is_enabled = isset($params['is_enabled']) ? (bool) $params['is_enabled'] : false;
		$position = isset($params['position']) ? sanitize_text_field($params['position']) : null;

		// Validate position if provided
		if ($position !== null && !in_array($position, ['L', 'R'], true)) {
			$error_response = Dobare_Utils::normalize_error_body(array('موقعیت نمایش نامعتبر است. فقط مقادیر L یا R مجاز هستند.'), 400);
			return new WP_REST_Response($error_response, 400);
		}

		// Get current settings to check if updates are actually needed
		$current_enabled = Dobare_Customer_Credit_Service::is_feature_enabled();
		$current_position = Dobare_Customer_Credit_Service::get_position();

		// Track if any actual changes were made
		$changes_made = false;

		// Update enabled status only if it's different from current
		if ($is_enabled !== $current_enabled) {
			$enabled_success = Dobare_Customer_Credit_Service::set_feature_enabled($is_enabled);
			if (!$enabled_success) {
				$error_response = Dobare_Utils::normalize_error_body(array('خطا در به‌روزرسانی وضعیت فعال/غیرفعال'), 500);
				return new WP_REST_Response($error_response, 500);
			}
			$changes_made = true;
		}

		// Update position only if it's different from current and provided
		if ($position !== null && $position !== $current_position) {
			$position_success = Dobare_Customer_Credit_Service::set_position($position);
			if (!$position_success) {
				$error_response = Dobare_Utils::normalize_error_body(array('خطا در به‌روزرسانی موقعیت نمایش'), 500);
				return new WP_REST_Response($error_response, 500);
			}
			$changes_made = true;
		}

		// Return success response with current settings
		$settings = array(
			'is_enabled' => $is_enabled,
			'position'   => Dobare_Customer_Credit_Service::get_position(),
			'message'    => $changes_made ? 'تنظیمات با موفقیت به‌روزرسانی شد' : 'تنظیمات بدون تغییر'
		);
		$normalized_response = Dobare_Utils::normalize_response_body($settings, 200);
		return new WP_REST_Response($normalized_response, 200);
	}

	/**
	 * Get credit with discount codes settings
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function get_credit_with_discount_settings(WP_REST_Request $request)
	{
		$settings = array(
			'is_enabled' => Dobare_Utils::is_credit_with_discount_enabled()
		);

		$normalized_response = Dobare_Utils::normalize_response_body($settings, 200);
		return new WP_REST_Response($normalized_response, 200);
	}

	/**
	 * Update credit with discount codes settings
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function update_credit_with_discount_settings(WP_REST_Request $request)
	{
		$params = $request->get_json_params();
		$is_enabled = isset($params['is_enabled']) ? (bool) $params['is_enabled'] : false;

		$success = Dobare_Utils::set_credit_with_discount_enabled($is_enabled);

		if ($success) {
			$settings = array(
				'is_enabled' => $is_enabled,
				'message' => $is_enabled ? 'استفاده از اعتبار در کنار کدهای تخفیف فعال شد' : 'استفاده از اعتبار در کنار کدهای تخفیف غیرفعال شد'
			);
			$normalized_response = Dobare_Utils::normalize_response_body($settings, 200);
			return new WP_REST_Response($normalized_response, 200);
		} else {
			$error_response = Dobare_Utils::normalize_error_body(array('خطا در به‌روزرسانی تنظیمات'), 500);
			return new WP_REST_Response($error_response, 500);
		}
	}

	/**
	 * Get minimum cart total settings for gift credit
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function get_minimum_cart_total_settings(WP_REST_Request $request)
	{
		$settings = array(
			'minimum_amount' => Dobare_Utils::get_minimum_cart_total_for_credit()
		);

		$normalized_response = Dobare_Utils::normalize_response_body($settings, 200);
		return new WP_REST_Response($normalized_response, 200);
	}

	/**
	 * Update minimum cart total settings for gift credit
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function update_minimum_cart_total_settings(WP_REST_Request $request)
	{
		$params = $request->get_json_params();
		$minimum_amount = isset($params['minimum_amount']) ? (int) $params['minimum_amount'] : 0;

		// Ensure amount is not negative
		$minimum_amount = max(0, $minimum_amount);

		$success = Dobare_Utils::set_minimum_cart_total_for_credit($minimum_amount);

		if ($success) {
			$settings = array(
				'minimum_amount' => $minimum_amount,
				'message' => $minimum_amount > 0
					? sprintf(
						'حداقل مبلغ سبد خرید برای استفاده از اعتبار هدیه به %s %s تنظیم شد',
						number_format($minimum_amount),
						\Dobare\Utils\Dobare_Utils::get_currency_word()
					)
					: 'حداقل مبلغ سبد خرید برای استفاده از اعتبار هدیه حذف شد'
			);
			$normalized_response = Dobare_Utils::normalize_response_body($settings, 200);
			return new WP_REST_Response($normalized_response, 200);
		} else {
			$error_response = Dobare_Utils::normalize_error_body(array('خطا در به‌روزرسانی تنظیمات'), 500);
			return new WP_REST_Response($error_response, 500);
		}
	}

	/**
	 * Get credit disable window settings.
	 *
	 * @param WP_REST_Request $request Request instance.
	 *
	 * @return WP_REST_Response
	 */
	public function get_credit_disable_window(WP_REST_Request $request): WP_REST_Response
	{
		$window     = Dobare_Utils::get_credit_disable_window();
		$timezone   = wp_timezone();
		$tz_string  = function_exists('wp_timezone_string') ? wp_timezone_string() : get_option('timezone_string');
		$start_site = null;
		$end_site   = null;

		if (! empty($window['start_utc']) && ! empty($window['end_utc'])) {
			try {
				$start_dt = new \DateTimeImmutable($window['start_utc'], new \DateTimeZone('UTC'));
				$end_dt   = new \DateTimeImmutable($window['end_utc'], new \DateTimeZone('UTC'));
				$start_site = $start_dt->setTimezone($timezone)->format('Y-m-d\TH:i');
				$end_site   = $end_dt->setTimezone($timezone)->format('Y-m-d\TH:i');
			} catch (\Exception $e) {
				$start_site = null;
				$end_site   = null;
			}
		}

		$payload = array(
			'start_utc' => $window['start_utc'],
			'end_utc'   => $window['end_utc'],
			'start_site' => $start_site,
			'end_site'   => $end_site,
			'timezone'   => $tz_string ?: 'UTC',
			'is_active'  => Dobare_Utils::is_credit_temporarily_disabled(),
		);

		$normalized_response = Dobare_Utils::normalize_response_body($payload, 200);

		return new WP_REST_Response($normalized_response, 200);
	}

	/**
	 * Update credit disable window settings.
	 *
	 * @param WP_REST_Request $request Request instance.
	 *
	 * @return WP_REST_Response
	 */
	public function update_credit_disable_window(WP_REST_Request $request): WP_REST_Response
	{
		$params    = $request->get_json_params();
		$start_raw = isset($params['start']) ? sanitize_text_field($params['start']) : '';
		$end_raw   = isset($params['end']) ? sanitize_text_field($params['end']) : '';

		if (empty($start_raw) || empty($end_raw)) {
			$error_response = Dobare_Utils::normalize_error_body(array('هر دو تاریخ شروع و پایان الزامی هستند'), 400);

			return new WP_REST_Response($error_response, 400);
		}

		try {
			$timezone = wp_timezone();
			$start_dt = new \DateTimeImmutable($start_raw, $timezone);
			$end_dt   = new \DateTimeImmutable($end_raw, $timezone);
		} catch (\Exception $e) {
			$error_response = Dobare_Utils::normalize_error_body(array('فرمت تاریخ/زمان نامعتبر است'), 400);

			return new WP_REST_Response($error_response, 400);
		}

		if ($end_dt <= $start_dt) {
			$error_response = Dobare_Utils::normalize_error_body(array('زمان پایان باید بعد از زمان شروع باشد'), 400);

			return new WP_REST_Response($error_response, 400);
		}

		$start_utc = $start_dt->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i:s');
		$end_utc   = $end_dt->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i:s');

		$saved = Dobare_Utils::set_credit_disable_window($start_utc, $end_utc);

		if (! $saved) {
			$error_response = Dobare_Utils::normalize_error_body(array('خطا در ذخیره بازه غیر فعال‌سازی'), 500);

			return new WP_REST_Response($error_response, 500);
		}

		$payload = array(
			'start_utc'  => $start_utc,
			'end_utc'    => $end_utc,
			'start_site' => $start_dt->format('Y-m-d\TH:i'),
			'end_site'   => $end_dt->format('Y-m-d\TH:i'),
			'timezone'   => function_exists('wp_timezone_string') ? wp_timezone_string() : get_option('timezone_string'),
			'is_active'  => Dobare_Utils::is_credit_temporarily_disabled(),
		);

		$normalized_response = Dobare_Utils::normalize_response_body($payload, 200);

		return new WP_REST_Response($normalized_response, 200);
	}

	/**
	 * Fetch current abandoned cart settings.
	 *
	 * @param WP_REST_Request $request Request instance.
	 *
	 * @return WP_REST_Response
	 */
	public function get_abandoned_cart_settings(WP_REST_Request $request)
	{
		$settings = array(
			'is_enabled'    => Dobare_Abandoned_Cart_Guard::is_feature_enabled(),
			'delay_minutes' => Dobare_Abandoned_Cart_Guard::get_delay_minutes(),
		);

		$normalized_response = Dobare_Utils::normalize_response_body($settings, 200);

		return new WP_REST_Response($normalized_response, 200);
	}

	/**
	 * Update abandoned cart reminder settings.
	 *
	 * @param WP_REST_Request $request Request instance.
	 *
	 * @return WP_REST_Response
	 */
	public function update_abandoned_cart_settings(WP_REST_Request $request)
	{
		$params = $request->get_json_params();

		$previous_state = Dobare_Abandoned_Cart_Guard::is_feature_enabled();
		$current_delay  = Dobare_Abandoned_Cart_Guard::get_delay_minutes();
		$min_delay      = Dobare_Abandoned_Cart_Guard::get_min_delay_minutes();
		$is_enabled = isset($params['is_enabled']) ? (bool) $params['is_enabled'] : false;
		$delay_minutes = isset($params['delay_minutes']) ? (int) $params['delay_minutes'] : $current_delay;

		if ($delay_minutes < $min_delay) {
			$delay_minutes = $min_delay;
		}

		$enabled_saved = Dobare_Utils::dob_update_option(Dobare_Abandoned_Cart_Guard::OPTION_ENABLED, $is_enabled);
		$delay_saved = Dobare_Utils::dob_update_option(Dobare_Abandoned_Cart_Guard::OPTION_DELAY_MINUTES, $delay_minutes);

		$enabled_ok = $enabled_saved || $previous_state === $is_enabled;
		$delay_ok   = $delay_saved || $current_delay === $delay_minutes;

		if ($enabled_ok && $delay_ok) {
			if ($previous_state && ! $is_enabled) {
				Dobare_Abandoned_Cart_Service::instance()->purge_all_rows();
			}

			$message = 'تنظیمات با موفقیت ذخیره شد.';
			if (! $previous_state && $is_enabled) {
				$message = 'یادآور سبد خرید رهاشده فعال شد.';
			} elseif ($previous_state && ! $is_enabled) {
				$message = 'یادآور سبد خرید رهاشده غیرفعال شد.';
			}

			$normalized_response = Dobare_Utils::normalize_response_body(
				array(
					'is_enabled'    => $is_enabled,
					'delay_minutes' => $delay_minutes,
					'message'       => $message,
				),
				200
			);

			return new WP_REST_Response($normalized_response, 200);
		}

		$error_response = Dobare_Utils::normalize_error_body(array('خطا در به‌روزرسانی تنظیمات'), 500);

		return new WP_REST_Response($error_response, 500);
	}

	/**
	 * Retrieve recent abandoned cart rows for diagnostics.
	 *
	 * @param WP_REST_Request $request Request instance.
	 *
	 * @return WP_REST_Response
	 */
	public function get_abandoned_cart_logs(WP_REST_Request $request)
	{
		$limit = $request->get_param('limit');
		$limit = is_numeric($limit) ? (int) $limit : 50;

		$logs = Dobare_Abandoned_Cart_Service::instance()->get_recent_rows($limit);

		$normalized_response = Dobare_Utils::normalize_response_body(
			array(
				'logs' => $logs,
			),
			200
		);

		return new WP_REST_Response($normalized_response, 200);
	}

	/**
	 * Purge all abandoned cart rows and cancel scheduled tasks.
	 *
	 * @param WP_REST_Request $request Request instance.
	 *
	 * @return WP_REST_Response
	 */
	public function purge_abandoned_cart_logs(WP_REST_Request $request)
	{
		$deleted = Dobare_Abandoned_Cart_Service::instance()->purge_all_rows();

		$normalized_response = Dobare_Utils::normalize_response_body(
			array(
				'deleted' => $deleted,
			),
			200
		);

		return new WP_REST_Response($normalized_response, 200);
	}

	/**
	 * Logout the user by clearing API key and onboarded status
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function logout(WP_REST_Request $request)
	{
		// Clear the API key
		$api_key_cleared = Dobare_Utils::dob_update_option(DOBARE_API_KEY_OPTION_KEY, false);

		// Set onboarded status to false
		$onboarded_cleared = Dobare_Utils::dob_update_option('ONBOARDED', false);

		if ($api_key_cleared && $onboarded_cleared) {
			$response_body = array(
				'status' => 'Success',
				'message' => 'خروج با موفقیت انجام شد'
			);
			$normalized_response = Dobare_Utils::normalize_response_body($response_body, 200);
			return new WP_REST_Response($normalized_response, 200);
		} else {
			$error_response = Dobare_Utils::normalize_error_body(array('خطا در انجام خروج'), 500);
			return new WP_REST_Response($error_response, 500);
		}
	}

	/**
	 * Get custom lead magnet HTML/CSS
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function get_custom_lead_magnet(WP_REST_Request $request)
	{
		// Get default templates directly from files
		$default_html = Dobare_Lead_Magnet_Service::get_default_html();
		$default_desktop_css = Dobare_Lead_Magnet_Service::get_default_css('desktop');
		$default_mobile_css = Dobare_Lead_Magnet_Service::get_default_css('mobile');

		// Get saved custom content
		$custom_desktop_html = Dobare_Utils::get_custom_lead_magnet_html('desktop');
		$custom_desktop_css = Dobare_Utils::get_custom_lead_magnet_css('desktop');
		$custom_mobile_html = Dobare_Utils::get_custom_lead_magnet_html('mobile');
		$custom_mobile_css = Dobare_Utils::get_custom_lead_magnet_css('mobile');

		$settings = array(
			'is_enabled'           => Dobare_Utils::is_custom_lead_magnet_enabled(),
			'desktop_html'         => $custom_desktop_html ?: '',
			'desktop_css'          => $custom_desktop_css ?: '',
			'mobile_html'          => $custom_mobile_html ?: '',
			'mobile_css'           => $custom_mobile_css ?: '',
			'default_desktop_html' => $default_html,
			'default_desktop_css'  => $default_desktop_css,
			'default_mobile_html'  => $default_html,
			'default_mobile_css'   => $default_mobile_css,
			'required_ids'         => \Dobare\Lead_Magnet\Dobare_Lead_Magnet_Validator::get_required_ids(),
		);

		$normalized_response = Dobare_Utils::normalize_response_body($settings, 200);
		return new WP_REST_Response($normalized_response, 200);
	}

	/**
	 * Update custom lead magnet HTML/CSS
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function update_custom_lead_magnet(WP_REST_Request $request)
	{
		$params = $request->get_json_params();

		// Handle enable/disable toggle
		if (isset($params['is_enabled'])) {
			Dobare_Utils::set_custom_lead_magnet_enabled((bool) $params['is_enabled']);
		}

		$desktop_html = isset($params['desktop_html']) ? $params['desktop_html'] : null;
		$desktop_css  = isset($params['desktop_css']) ? $params['desktop_css'] : null;
		$mobile_html  = isset($params['mobile_html']) ? $params['mobile_html'] : null;
		$mobile_css   = isset($params['mobile_css']) ? $params['mobile_css'] : null;

		// Sanitize first, then validate the sanitized content
		// Desktop
		$sanitized_desktop_html = $desktop_html !== null ? \Dobare\Lead_Magnet\Dobare_Lead_Magnet_Validator::sanitize_html($desktop_html) : null;
		$sanitized_desktop_css  = $desktop_css !== null ? \Dobare\Lead_Magnet\Dobare_Lead_Magnet_Validator::sanitize_css($desktop_css) : null;

		// Mobile
		$sanitized_mobile_html = $mobile_html !== null ? \Dobare\Lead_Magnet\Dobare_Lead_Magnet_Validator::sanitize_html($mobile_html) : null;
		$sanitized_mobile_css  = $mobile_css !== null ? \Dobare\Lead_Magnet\Dobare_Lead_Magnet_Validator::sanitize_css($mobile_css) : null;

		// Validate sanitized desktop content if provided
		if ($sanitized_desktop_html !== null || $sanitized_desktop_css !== null) {
			$validation = \Dobare\Lead_Magnet\Dobare_Lead_Magnet_Validator::validate_custom_content(
				$sanitized_desktop_html ?: '',
				$sanitized_desktop_css ?: ''
			);

			if (!$validation['valid']) {
				$error_response = Dobare_Utils::normalize_error_body($validation['errors'], 400);
				return new WP_REST_Response($error_response, 400);
			}
		}

		// Validate sanitized mobile content if provided
		if ($sanitized_mobile_html !== null || $sanitized_mobile_css !== null) {
			$validation = \Dobare\Lead_Magnet\Dobare_Lead_Magnet_Validator::validate_custom_content(
				$sanitized_mobile_html ?: '',
				$sanitized_mobile_css ?: ''
			);

			if (!$validation['valid']) {
				$error_response = Dobare_Utils::normalize_error_body($validation['errors'], 400);
				return new WP_REST_Response($error_response, 400);
			}
		}

		// Save sanitized content
		if ($sanitized_desktop_html !== null) {
			Dobare_Utils::set_custom_lead_magnet_html($sanitized_desktop_html, 'desktop');
		}
		if ($sanitized_desktop_css !== null) {
			Dobare_Utils::set_custom_lead_magnet_css($sanitized_desktop_css, 'desktop');
		}
		if ($sanitized_mobile_html !== null) {
			Dobare_Utils::set_custom_lead_magnet_html($sanitized_mobile_html, 'mobile');
		}
		if ($sanitized_mobile_css !== null) {
			Dobare_Utils::set_custom_lead_magnet_css($sanitized_mobile_css, 'mobile');
		}

		$response_body = array('message' => 'تنظیمات سفارشی‌سازی با موفقیت ذخیره شد');
		$normalized_response = Dobare_Utils::normalize_response_body($response_body, 200);
		return new WP_REST_Response($normalized_response, 200);
	}

	/**
	 * Preview custom lead magnet
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function preview_custom_lead_magnet(WP_REST_Request $request)
	{
		$params = $request->get_json_params();

		$html   = isset($params['html']) ? $params['html'] : '';
		$css    = isset($params['css']) ? $params['css'] : '';
		$device = isset($params['device']) ? $params['device'] : 'desktop';

		// Validate before preview
		$validation = \Dobare\Lead_Magnet\Dobare_Lead_Magnet_Validator::validate_custom_content($html, $css);

		if (!$validation['valid']) {
			$error_response = Dobare_Utils::normalize_error_body($validation['errors'], 400);
			return new WP_REST_Response($error_response, 400);
		}

		// Sanitize content
		$sanitized_html = \Dobare\Lead_Magnet\Dobare_Lead_Magnet_Validator::sanitize_html($html);
		$sanitized_css  = \Dobare\Lead_Magnet\Dobare_Lead_Magnet_Validator::sanitize_css($css);

		// Generate preview (returns array with html and position)
		$preview_result = \Dobare\Lead_Magnet\Dobare_Lead_Magnet_Validator::render_preview(
			$sanitized_html,
			$sanitized_css,
			$device
		);

		$response_body = array(
			'preview'  => $preview_result['html'],
			'position' => $preview_result['position'],
		);
		$normalized_response = Dobare_Utils::normalize_response_body($response_body, 200);
		return new WP_REST_Response($normalized_response, 200);
	}

	/**
	 * Reset custom lead magnet to defaults
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function reset_custom_lead_magnet(WP_REST_Request $request)
	{
		// Clear custom content and disable
		$success = Dobare_Utils::clear_custom_lead_magnet();
		Dobare_Utils::set_custom_lead_magnet_enabled(false);

		if ($success) {
			// Return default templates directly from files
			$default_html = Dobare_Lead_Magnet_Service::get_default_html();
			$default_desktop_css = Dobare_Lead_Magnet_Service::get_default_css('desktop');
			$default_mobile_css = Dobare_Lead_Magnet_Service::get_default_css('mobile');

			$response_body = array(
				'message'      => 'قالب لید مگنت به حالت پیش‌فرض بازگشت',
				'desktop_html' => $default_html,
				'desktop_css'  => $default_desktop_css,
				'mobile_html'  => $default_html,
				'mobile_css'   => $default_mobile_css,
			);
			$normalized_response = Dobare_Utils::normalize_response_body($response_body, 200);
			return new WP_REST_Response($normalized_response, 200);
		} else {
			$error_response = Dobare_Utils::normalize_error_body(array('خطا در بازگشت به حالت پیش‌فرض'), 500);
			return new WP_REST_Response($error_response, 500);
		}
	}
}
