<?php

declare(strict_types=1);

namespace Signocore\Multilanguage\Features;

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

use Signocore\Multilanguage\Application\Entitlements;
use Signocore\Multilanguage\Application\LicenseManager;
use Signocore\Multilanguage\Infrastructure\Traits\Singleton;

/**
 * Scans the database for dynamic translatable strings and registers them.
 */
final class StringScanner
{
	use Singleton;

	private const TRANSIENT_KEY = 'sml_last_full_scan';

	private const SCAN_INTERVAL = 43200; // 12 hours

	protected function init(): void
	{
		// Scanning is triggered on-demand by StringTranslationPage, not on admin_init.
	}

	/**
	 * Whether a scan should run (no recent scan found).
	 */
	public function shouldScan(): bool
	{
		return !get_transient(self::TRANSIENT_KEY);
	}

	/**
	 * Run a full scan of all available string sources.
	 */
	public function runFullScan(): void
	{
		$languages = LanguageManager::load()->getActiveLanguages();
		if (count($languages) > 1) {
			$this->scanWordPress();
			$this->scanWidgets();

			if ($this->isWooCommerceAvailable()) {
				$this->scanWooCommerce();
			}
		}

		set_transient(self::TRANSIENT_KEY, time(), self::SCAN_INTERVAL);
	}

	/**
	 * Delete the scan cache and run a fresh scan.
	 */
	public function forceRescan(): void
	{
		delete_transient(self::TRANSIENT_KEY);
		$this->runFullScan();
	}

	/**
	 * Scan WordPress core options.
	 */
	private function scanWordPress(): void
	{
		$this->register('WordPress', 'blogname', get_option('blogname', ''));
		$this->register('WordPress', 'blogdescription', get_option('blogdescription', ''));
	}

	/**
	 * Scan widget titles and text content.
	 */
	private function scanWidgets(): void
	{
		$sidebars = get_option('sidebars_widgets', []);
		if (!is_array($sidebars)) {
			return;
		}

		// Collect all active widget IDs
		$activeWidgetIds = [];
		foreach ($sidebars as $sidebarId => $widgets) {
			if ($sidebarId === 'wp_inactive_widgets' || !is_array($widgets)) {
				continue;
			}
			foreach ($widgets as $widgetId) {
				$activeWidgetIds[] = $widgetId;
			}
		}

		if (empty($activeWidgetIds)) {
			return;
		}

		// Group widget IDs by their base type (e.g., 'text-2' → 'text')
		$widgetsByBase = [];
		foreach ($activeWidgetIds as $widgetId) {
			if (preg_match('/^(.+)-(\d+)$/', $widgetId, $matches)) {
				$base = $matches[1];
				$number = (int) $matches[2];
				$widgetsByBase[$base][$number] = $widgetId;
			}
		}

		foreach ($widgetsByBase as $base => $instances) {
			$optionName = 'widget_' . $base;
			$allInstances = get_option($optionName, []);
			if (!is_array($allInstances)) {
				continue;
			}

			foreach ($instances as $number => $widgetId) {
				$instance = $allInstances[$number] ?? null;
				if (!is_array($instance)) {
					continue;
				}

				// Title (common to nearly all widgets)
				if (!empty($instance['title']) && is_string($instance['title'])) {
					$this->register('Widgets', $widgetId . '_title', $instance['title']);
				}

				// Text widget content
				if ($base === 'text' && !empty($instance['text']) && is_string($instance['text'])) {
					$this->register('Widgets', $widgetId . '_text', $instance['text'], 'text');
				}

				// Custom HTML widget content
				if ($base === 'custom_html' && !empty($instance['content']) && is_string($instance['content'])) {
					$this->register('Widgets', $widgetId . '_content', $instance['content'], 'text');
				}

				// Block widget content (WordPress 5.8+)
				if ($base === 'block' && !empty($instance['content']) && is_string($instance['content'])) {
					$this->register('Widgets', $widgetId . '_content', $instance['content'], 'text');
				}

				// Image widget caption and alt text
				if ($base === 'media_image') {
					if (!empty($instance['caption']) && is_string($instance['caption'])) {
						$this->register('Widgets', $widgetId . '_caption', $instance['caption']);
					}
					if (!empty($instance['alt']) && is_string($instance['alt'])) {
						$this->register('Widgets', $widgetId . '_alt', $instance['alt']);
					}
				}
			}
		}
	}

	/**
	 * Scan all WooCommerce string sources.
	 */
	private function scanWooCommerce(): void
	{
		$this->scanWooCommerceEmails();
		$this->scanWooCommerceGateways();
		$this->scanWooCommerceShipping();
		$this->scanWooCommerceAttributes();
	}

	/**
	 * Scan WooCommerce email subjects, headings, and additional content.
	 */
	private function scanWooCommerceEmails(): void
	{
		$mailer = WC()->mailer();
		if ($mailer === null) {
			return;
		}

		$emails = $mailer->get_emails();
		if (!is_array($emails)) {
			return;
		}

		foreach ($emails as $email) {
			$id = $email->id ?? '';
			if ($id === '') {
				continue;
			}

			$subject = $email->get_option('subject', '');
			if ($subject === '') {
				$subject = $email->get_default_subject();
			}
			$this->register('WooCommerce', "email_{$id}_subject", $subject);

			$heading = $email->get_option('heading', '');
			if ($heading === '') {
				$heading = $email->get_default_heading();
			}
			$this->register('WooCommerce', "email_{$id}_heading", $heading);

			$additionalContent = $email->get_option('additional_content', '');
			if ($additionalContent !== '') {
				$this->register('WooCommerce', "email_{$id}_additional_content", $additionalContent, 'text');
			}
		}
	}

	/**
	 * Scan WooCommerce payment gateway titles and descriptions.
	 */
	private function scanWooCommerceGateways(): void
	{
		$gateways = WC()->payment_gateways();
		if ($gateways === null) {
			return;
		}

		foreach ($gateways->payment_gateways() as $gateway) {
			$id = $gateway->id ?? '';
			if ($id === '' || ($gateway->enabled ?? 'no') !== 'yes') {
				continue;
			}

			$this->register('WooCommerce', "gateway_{$id}_title", $gateway->get_title());

			$description = $gateway->get_description();
			if ($description !== '') {
				$this->register('WooCommerce', "gateway_{$id}_description", $description, 'text');
			}
		}
	}

	/**
	 * Scan WooCommerce shipping method titles.
	 */
	private function scanWooCommerceShipping(): void
	{
		if (!class_exists('WC_Shipping_Zones')) {
			return;
		}

		$zones = \WC_Shipping_Zones::get_zones();
		$zones[] = ['zone_id' => 0]; // "Rest of the World" zone

		foreach ($zones as $zoneData) {
			$zone = new \WC_Shipping_Zone($zoneData['zone_id']);

			foreach ($zone->get_shipping_methods(true) as $method) {
				$instanceId = $method->get_instance_id();
				if ($instanceId <= 0) {
					continue;
				}

				$title = $method->get_title();
				if ($title !== '') {
					$this->register('WooCommerce', "shipping_{$instanceId}_title", $title);
				}
			}
		}
	}

	/**
	 * Scan WooCommerce product attribute labels.
	 */
	private function scanWooCommerceAttributes(): void
	{
		if (!function_exists('wc_get_attribute_taxonomies')) {
			return;
		}

		$attributes = wc_get_attribute_taxonomies();
		if (!is_array($attributes)) {
			return;
		}

		foreach ($attributes as $attribute) {
			$name = $attribute->attribute_name ?? '';
			$label = $attribute->attribute_label ?? '';

			if ($name !== '' && $label !== '') {
				$this->register('WooCommerce', "attribute_{$name}", $label);
			}
		}
	}

	/**
	 * Check if WooCommerce is available and licensed.
	 */
	private function isWooCommerceAvailable(): bool
	{
		return class_exists('WooCommerce')
			&& function_exists('WC')
			&& LicenseManager::load()->can(Entitlements::WOOCOMMERCE);
	}

	/**
	 * Register a translatable string (skips empty values).
	 */
	private function register(string $context, string $name, string $value, string $type = 'line'): void
	{
		if ($value === '') {
			return;
		}

		do_action('signocore_ml_register_string', $context, $name, $value, $type);
	}
}
