<?php
if (! defined('ABSPATH')) exit;

/**
 * Storzen — License Manager
 *
 * Calls the PaddlePay license API at webtend.net to activate / deactivate / check
 * the license on the current domain.  Status is cached in a transient (12 h) and
 * persisted in wp_options as a last-known-good fallback.
 */
class Storzen_License
{

	const OPTION_KEY  = 'storzen_license_key';
	const OPTION_DATA = 'storzen_license_data';
	const TRANSIENT   = 'storzen_license_cache';
	const CRON_HOOK   = 'storzen_license_check';
	const API_URL     = 'https://webtend.net/wp-json/paddlepay/v1/license/verify';
	const CACHE_HOURS = 12;

	private static $instance = null;

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

	private function __construct()
	{
		add_action('admin_menu',                     [$this, 'add_menu'], 30);
		add_action('wp_ajax_szp_license_activate',   [$this, 'ajax_activate']);
		add_action('wp_ajax_szp_license_deactivate', [$this, 'ajax_deactivate']);
		add_action('wp_ajax_szp_license_refresh',    [$this, 'ajax_refresh']);
		add_action(self::CRON_HOOK,                  [$this, 'cron_refresh']);

		if (! wp_next_scheduled(self::CRON_HOOK)) {
			wp_schedule_event(time(), 'daily', self::CRON_HOOK);
		}
	}

	// ── Public API ─────────────────────────────────────────────────────────

	public static function get_domain()
	{
		return (string) wp_parse_url(home_url(), PHP_URL_HOST);
	}

	public static function get_key()
	{
		return (string) get_option(self::OPTION_KEY, '');
	}

	/**
	 * Fast status check — reads only from cache / stored options, no remote call.
	 * Safe to call at plugin boot (plugins_loaded / init).
	 */
	public static function is_active()
	{
		$data = get_transient(self::TRANSIENT);
		if ($data === false) {
			$data = get_option(self::OPTION_DATA, []);
		}
		if (! is_array($data) || empty($data['status'])) {
			return false;
		}
		$domain = self::get_domain();
		$acts   = is_array($data['activations'] ?? null) ? $data['activations'] : [];
		return $data['status'] === 'active' && in_array($domain, $acts, true);
	}

	// ── Remote API ─────────────────────────────────────────────────────────

	private static function api($action, $key = null, $domain = null)
	{
		if (! $key) $key = self::get_key();

		$body = ['license_key' => $key, 'action' => $action];
		if ($domain) $body['domain'] = $domain;

		$response = wp_remote_post(self::API_URL, [
			'timeout'    => 15,
			'body'       => $body,
			'user-agent' => 'Storzen/' . STORZEN_VERSION . '; ' . home_url(),
		]);

		if (is_wp_error($response)) return $response;

		$decoded = json_decode(wp_remote_retrieve_body($response), true);
		return is_array($decoded) ? $decoded : [];
	}

	private static function store_data($data)
	{
		set_transient(self::TRANSIENT, $data, self::CACHE_HOURS * HOUR_IN_SECONDS);
		update_option(self::OPTION_DATA, $data);
	}

	private static function clear_data()
	{
		delete_option(self::OPTION_KEY);
		delete_option(self::OPTION_DATA);
		delete_transient(self::TRANSIENT);
	}

	// ── Cron ───────────────────────────────────────────────────────────────

	public function cron_refresh()
	{
		if (! self::get_key()) return;
		$data = self::api('check');
		if (! is_wp_error($data) && ! empty($data['success'])) {
			self::store_data($data);
		}
	}

	// ── AJAX handlers ──────────────────────────────────────────────────────

	public function ajax_activate()
	{
		check_ajax_referer('szp_license_nonce', 'nonce');
		if (! current_user_can('manage_options')) {
			wp_send_json_error(['message' => __('Forbidden.', 'storzen')]);
		}

		$key = sanitize_text_field(wp_unslash($_POST['license_key'] ?? ''));
		if (! $key) {
			wp_send_json_error(['message' => __('License key is required.', 'storzen')]);
		}

		$result = self::api('activate', $key, self::get_domain());

		if (is_wp_error($result)) {
			wp_send_json_error(['message' => $result->get_error_message()]);
		}
		if (empty($result['success'])) {
			wp_send_json_error($result);
		}

		update_option(self::OPTION_KEY, $key);

		// Fetch full status to store activations list
		$check = self::api('check', $key);
		if (! is_wp_error($check) && ! empty($check['success'])) {
			self::store_data($check);
		}

		wp_send_json_success($result);
	}

	public function ajax_deactivate()
	{
		check_ajax_referer('szp_license_nonce', 'nonce');
		if (! current_user_can('manage_options')) {
			wp_send_json_error(['message' => __('Forbidden.', 'storzen')]);
		}

		$result = self::api('deactivate', null, self::get_domain());

		if (is_wp_error($result)) {
			wp_send_json_error(['message' => $result->get_error_message()]);
		}

		self::clear_data();
		wp_send_json_success($result);
	}

	public function ajax_refresh()
	{
		check_ajax_referer('szp_license_nonce', 'nonce');
		if (! current_user_can('manage_options')) {
			wp_send_json_error(['message' => __('Forbidden.', 'storzen')]);
		}

		delete_transient(self::TRANSIENT);

		$data = self::api('check');
		if (is_wp_error($data)) {
			wp_send_json_error(['message' => $data->get_error_message()]);
		}
		if (empty($data['success'])) {
			wp_send_json_error(['message' => $data['message'] ?? __('Could not verify license.', 'storzen')]);
		}

		self::store_data($data);
		wp_send_json_success($data);
	}

	// ── Admin submenu ──────────────────────────────────────────────────────

	public function add_menu()
	{
		// add_submenu_page(
		// 	'storzen',
		// 	__('License', 'storzen'),
		// 	__('License 🔑', 'storzen'),
		// 	'manage_options',
		// 	'storzen-license',
		// 	[$this, 'render_page']
		// );
	}

	// ── Admin page ─────────────────────────────────────────────────────────

	public function render_page()
	{
		$key  = self::get_key();
		$data = get_transient(self::TRANSIENT);

		// Refresh from API when cache is empty (but only on this page, not on every admin load)
		if ($data === false && $key) {
			$fresh = self::api('check');
			if (! is_wp_error($fresh) && ! empty($fresh['success'])) {
				self::store_data($fresh);
				$data = $fresh;
			}
		}
		if (! is_array($data)) {
			$data = get_option(self::OPTION_DATA, []);
		}

		$status     = $data['status']     ?? '';
		$plan       = $data['plan_label'] ?? '';
		$site_limit = isset($data['site_limit']) ? (int) $data['site_limit'] : 0;
		$expires    = $data['expires_at'] ?? '';
		$acts       = is_array($data['activations'] ?? null) ? $data['activations'] : [];
		$domain     = self::get_domain();
		$activated  = $status === 'active' && in_array($domain, $acts, true);

		// Status badge HTML
		if ($activated) {
			$badge = '<span class="szp-badge szp-badge--active">Active</span>';
		} elseif ($status === 'expired') {
			$badge = '<span class="szp-badge szp-badge--error">Expired</span>';
		} elseif ($status === 'revoked') {
			$badge = '<span class="szp-badge szp-badge--error">Revoked</span>';
		} elseif ($key && $status === 'active' && ! $activated) {
			$badge = '<span class="szp-badge szp-badge--warn">Not Activated Here</span>';
		} else {
			$badge = '<span class="szp-badge szp-badge--inactive">Inactive</span>';
		}

?>
		<div class="wrap szp-lic-wrap">
			<h1><?php esc_html_e('Storzen — License', 'storzen'); ?></h1>

			<div id="szp-notice"></div>

			<div class="szp-lic-grid">

				<!-- ── Current license card ────────────────────────────────── -->
				<div class="szp-lic-card">

					<div class="szp-lic-head">
						<h2><?php esc_html_e('Current license', 'storzen'); ?></h2>
					</div>

					<?php if ($activated) : ?>

						<p class="szp-lic-status">
							<span class="szp-check" aria-hidden="true">✓</span>
							<strong><?php
									/* translators: %s: plan label, e.g. "Storzen" */
									printf(esc_html__('Active — %s', 'storzen'), esc_html($plan ? $plan : 'Storzen'));
									?></strong>
						</p>

						<label for="szp-license-key-display" class="szp-field-label">
							<?php esc_html_e('License key', 'storzen'); ?>
						</label>
						<input type="password" id="szp-license-key-display" class="regular-text szp-readonly-key"
							value="<?php echo esc_attr($key); ?>" readonly>

						<?php if ($plan || $site_limit || $expires || $acts) : ?>
							<table class="szp-info-tbl">
								<?php if ($site_limit) : ?>
									<tr>
										<th><?php esc_html_e('Site Limit', 'storzen'); ?></th>
										<td><?php echo $site_limit >= 999 ? esc_html__('Unlimited', 'storzen') : esc_html($site_limit . ' site(s)'); ?></td>
									</tr>
								<?php endif; ?>
								<tr>
									<th><?php esc_html_e('Expiry', 'storzen'); ?></th>
									<td>
										<?php
										if ($expires) {
											echo esc_html(date_i18n(get_option('date_format'), strtotime($expires)));
										} else {
											echo '<span style="color:#16a34a">' . esc_html__('Lifetime', 'storzen') . ' ♾</span>';
										}
										?>
									</td>
								</tr>
								<tr>
									<th><?php esc_html_e('Domain', 'storzen'); ?></th>
									<td><strong><?php echo esc_html($domain); ?></strong></td>
								</tr>
							</table>
						<?php endif; ?>

						<div class="szp-lic-actions">
							<button id="szp-btn-deactivate" class="button button-secondary" type="button">
								<?php esc_html_e('Deactivate license', 'storzen'); ?>
							</button>
							<button id="szp-btn-refresh" class="button" type="button">
								<?php esc_html_e('Refresh', 'storzen'); ?>
							</button>
						</div>

					<?php else : ?>

						<p class="szp-lic-status szp-lic-status--inactive">
							<?php echo $badge; // phpcs:ignore WordPress.Security.EscapeOutput 
							?>
						</p>

						<?php if ($key && $status === 'active' && ! $activated) : ?>
							<p class="szp-notice-warn">
								<?php
								printf(
									/* translators: %s: domain name */
									esc_html__('⚠ This license is valid but not yet activated on %s. Click Activate to use it here.', 'storzen'),
									'<strong>' . esc_html($domain) . '</strong>'
								);
								?>
							</p>
						<?php endif; ?>

						<label for="szp-license-key" class="szp-field-label">
							<?php esc_html_e('License key', 'storzen'); ?>
						</label>
						<input type="text" id="szp-license-key" class="regular-text szp-key-input"
							placeholder="XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX"
							value="<?php echo esc_attr($key); ?>" autocomplete="off" spellcheck="false">

						<div class="szp-lic-actions">
							<button id="szp-btn-activate" class="button button-primary" type="button">
								<?php esc_html_e('Activate license', 'storzen'); ?>
							</button>
						</div>

						<p class="szp-lic-footer">
							<a href="https://storzen.webtend.net/pricing/" target="_blank" rel="noopener noreferrer">
								<?php esc_html_e("Don't have a license? Get Storzen →", 'storzen'); ?>
							</a>
						</p>

					<?php endif; ?>

				</div><!-- .szp-lic-card -->

				<!-- ── Pro benefits card ───────────────────────────────────── -->
				<div class="szp-lic-card szp-benefits-card">
					<div class="szp-lic-head">
						<h2><?php esc_html_e('Pro benefits', 'storzen'); ?></h2>
					</div>
					<ul class="szp-benefits">
						<li><span class="szp-check" aria-hidden="true">✓</span><?php esc_html_e('Premium Elementor widgets &amp; templates', 'storzen'); ?></li>
						<li><span class="szp-check" aria-hidden="true">✓</span><?php esc_html_e('Advanced WooCommerce shop &amp; product layouts', 'storzen'); ?></li>
						<li><span class="szp-check" aria-hidden="true">✓</span><?php esc_html_e('Full design controls (fonts, colors, animations)', 'storzen'); ?></li>
						<li><span class="szp-check" aria-hidden="true">✓</span><?php esc_html_e('Conversion-focused cart &amp; checkout enhancements', 'storzen'); ?></li>
						<li><span class="szp-check" aria-hidden="true">✓</span><?php esc_html_e('Priority email support', 'storzen'); ?></li>
					</ul>
				</div>

			</div><!-- .szp-lic-grid -->

		</div><!-- .wrap -->

		<style>
			.szp-lic-wrap {
				max-width: 1100px;
			}

			.szp-lic-grid {
				display: grid;
				grid-template-columns: 1fr 1fr;
				gap: 20px;
				margin-top: 20px;
			}

			@media (max-width: 860px) {
				.szp-lic-grid {
					grid-template-columns: 1fr;
				}
			}

			.szp-lic-card {
				background: #fff;
				border: 1px solid #e5e7eb;
				border-radius: 10px;
				padding: 24px 28px;
			}

			.szp-lic-head {
				display: flex;
				align-items: center;
				justify-content: space-between;
				gap: 14px;
				margin-bottom: 18px;
			}

			.szp-lic-head h2 {
				margin: 0;
				font-size: 15px;
				font-weight: 700;
				color: #111827;
			}

			.szp-lic-status {
				display: flex;
				align-items: center;
				gap: 8px;
				font-size: 15px;
				color: #15803d;
				margin: 0 0 18px;
			}

			.szp-lic-status--inactive {
				color: #6b7280;
			}

			.szp-check {
				display: inline-flex;
				align-items: center;
				justify-content: center;
				width: 18px;
				height: 18px;
				border-radius: 50%;
				background: #22c55e;
				color: #fff;
				font-size: 11px;
				font-weight: 700;
				line-height: 1;
				flex-shrink: 0;
			}

			.szp-field-label {
				display: block;
				font-size: 12px;
				font-weight: 600;
				color: #374151;
				margin: 6px 0 6px;
			}

			.szp-readonly-key,
			.szp-key-input {
				width: 100%;
				max-width: 100%;
				font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
				letter-spacing: 1px;
				background: #f3f4f6;
			}

			.szp-key-input {
				background: #fff;
			}

			.szp-info-tbl {
				border-collapse: collapse;
				width: 100%;
				margin: 16px 0 18px;
				font-size: 13px;
			}

			.szp-info-tbl th {
				text-align: left;
				font-weight: 600;
				color: #6b7280;
				padding: 6px 12px 6px 0;
				width: 120px;
				white-space: nowrap;
			}

			.szp-info-tbl td {
				padding: 6px 0;
				color: #111827;
			}

			.szp-lic-actions {
				display: flex;
				gap: 10px;
				flex-wrap: wrap;
				margin-top: 16px;
			}

			.szp-lic-footer {
				margin: 18px 0 0;
				padding-top: 16px;
				border-top: 1px solid #f3f4f6;
				font-size: 13px;
			}

			.szp-benefits {
				margin: 0;
				padding: 0;
				list-style: none;
			}

			.szp-benefits li {
				display: flex;
				align-items: flex-start;
				gap: 10px;
				padding: 7px 0;
				font-size: 14px;
				color: #1f2937;
				line-height: 1.45;
			}

			.szp-benefits .szp-check {
				margin-top: 2px;
			}

			.szp-notice-wrap {
				padding: 12px 16px;
				border-radius: 0 6px 6px 0;
				margin-bottom: 16px;
				font-size: 13px;
			}

			.szp-notice-success {
				background: #f0fdf4;
				border-left: 4px solid #22c55e;
			}

			.szp-notice-error {
				background: #fef2f2;
				border-left: 4px solid #ef4444;
			}

			.szp-notice-warn {
				background: #fef9c3;
				border-left: 4px solid #eab308;
				padding: 10px 14px;
				border-radius: 0 6px 6px 0;
				margin-bottom: 16px;
				font-size: 13px;
			}

			.szp-badge {
				display: inline-block;
				padding: 3px 12px;
				border-radius: 20px;
				font-size: 12px;
				font-weight: 700;
			}

			.szp-badge--active {
				background: #dcfce7;
				color: #166534;
			}

			.szp-badge--error {
				background: #fee2e2;
				color: #991b1b;
			}

			.szp-badge--warn {
				background: #fef9c3;
				color: #854d0e;
			}

			.szp-badge--inactive {
				background: #f3f4f6;
				color: #374151;
			}
		</style>

		<script>
			(function($) {
				var ajaxUrl = <?php echo wp_json_encode(admin_url('admin-ajax.php')); ?>;
				var nonce = <?php echo wp_json_encode(wp_create_nonce('szp_license_nonce')); ?>;

				function notice(msg, type) {
					var cls = type === 'success' ? 'szp-notice-success' : 'szp-notice-error';
					$('#szp-notice').html('<div class="szp-notice-wrap ' + cls + '">' + msg + '</div>');
					$('html,body').animate({
						scrollTop: 0
					}, 180);
				}

				function busy(btn, state) {
					if (state) {
						btn.data('orig', btn.text()).text('…').prop('disabled', true);
					} else {
						btn.text(btn.data('orig') || btn.text()).prop('disabled', false);
					}
				}

				$('#szp-btn-activate').on('click', function() {
					var btn = $(this);
					var key = $('#szp-license-key').val().trim();
					if (!key) {
						notice('<?php echo esc_js(__('Please enter your license key.', 'storzen')); ?>', 'error');
						return;
					}
					busy(btn, true);
					$.post(ajaxUrl, {
						action: 'szp_license_activate',
						nonce: nonce,
						license_key: key
					}, function(res) {
						if (res.success) {
							notice('<?php echo esc_js(__('License activated successfully! Reloading…', 'storzen')); ?>', 'success');
							setTimeout(function() {
								location.reload();
							}, 1400);
						} else {
							notice((res.data && res.data.message) || '<?php echo esc_js(__('Activation failed.', 'storzen')); ?>', 'error');
							busy(btn, false);
						}
					}).fail(function() {
						notice('<?php echo esc_js(__('Request failed. Please try again.', 'storzen')); ?>', 'error');
						busy(btn, false);
					});
				});

				$('#szp-btn-deactivate').on('click', function() {
					if (!confirm('<?php echo esc_js(__('Deactivate this license on the current domain?', 'storzen')); ?>')) return;
					var btn = $(this);
					busy(btn, true);
					$.post(ajaxUrl, {
						action: 'szp_license_deactivate',
						nonce: nonce
					}, function(res) {
						if (res.success) {
							notice('<?php echo esc_js(__('License deactivated. Reloading…', 'storzen')); ?>', 'success');
							setTimeout(function() {
								location.reload();
							}, 1400);
						} else {
							notice((res.data && res.data.message) || '<?php echo esc_js(__('Deactivation failed.', 'storzen')); ?>', 'error');
							busy(btn, false);
						}
					}).fail(function() {
						notice('<?php echo esc_js(__('Request failed. Please try again.', 'storzen')); ?>', 'error');
						busy(btn, false);
					});
				});

				$('#szp-btn-refresh').on('click', function() {
					var btn = $(this);
					busy(btn, true);
					$.post(ajaxUrl, {
						action: 'szp_license_refresh',
						nonce: nonce
					}, function(res) {
						if (res.success) {
							notice('<?php echo esc_js(__('Status refreshed. Reloading…', 'storzen')); ?>', 'success');
							setTimeout(function() {
								location.reload();
							}, 1400);
						} else {
							notice((res.data && res.data.message) || '<?php echo esc_js(__('Could not verify license.', 'storzen')); ?>', 'error');
							busy(btn, false);
						}
					}).fail(function() {
						notice('<?php echo esc_js(__('Request failed.', 'storzen')); ?>', 'error');
						busy(btn, false);
					});
				});
			})(jQuery);
		</script>
<?php
	}

	// ── Helpers ────────────────────────────────────────────────────────────

	private static function mask_key($key)
	{
		if (strlen($key) <= 16) return $key;
		$shown = 8;
		return substr($key, 0, $shown)
			. str_repeat('·', strlen($key) - $shown * 2)
			. substr($key, -$shown);
	}
}
