<?php
/**
 * Monitors product stock levels and triggers notifications.
 *
 * @package StockGuardianPro
 */

declare(strict_types=1);

namespace StockGuardianPro\LowStock\Services;

use StockGuardianPro\LowStock\Plugin;
use WC_Product;

\defined('ABSPATH') || exit;

final class StockMonitorService implements ServiceInterface
{
    private Plugin $plugin;

    private ThresholdRepository $thresholds;

    private NotificationService $notifier;

    public function __construct(Plugin $plugin)
    {
        $this->plugin     = $plugin;
        $this->thresholds = new ThresholdRepository($plugin);
        $this->notifier   = $this->resolve_notifier($plugin);
    }

    public function register(): void
    {
        // Hook nativi WooCommerce per stock changes
        add_action('woocommerce_low_stock', [$this, 'handle_low_stock'], 10, 1);
        add_action('woocommerce_variation_set_stock', [$this, 'handle_stock_change'], 10, 1);
        add_action('woocommerce_product_set_stock', [$this, 'handle_stock_change'], 10, 1);
        
        // Hook per catturare modifiche manuali quando i prodotti vengono salvati
        // Usa priorità alta per evitare conflitti con altri hook
        add_action('woocommerce_update_product', [$this, 'handle_product_update'], 5, 1);
        add_action('woocommerce_update_product_variation', [$this, 'handle_product_update'], 5, 1);
    }

    public function handle_low_stock(WC_Product $product): void
    {
        $this->maybe_notify($product);
    }

    public function handle_stock_change(WC_Product $product): void
    {
        $this->maybe_notify($product);
    }

    /**
     * Gestisce l'aggiornamento di un prodotto (quando viene salvato manualmente).
     *
     * @param int $product_id ID del prodotto.
     */
    public function handle_product_update(int $product_id): void
    {
        $product = wc_get_product($product_id);
        if (! $product instanceof WC_Product) {
            return;
        }

        // Verifica se lo stock è gestito
        if (! $product->managing_stock()) {
            return;
        }

        $this->maybe_notify($product);
    }


    private function maybe_notify(WC_Product $product): void
    {
        $stock_quantity = $product->get_stock_quantity();

        if ($stock_quantity === null) {
            return;
        }

        $base_product_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
        $variation_id    = $product->is_type('variation') ? $product->get_id() : 0;

        $threshold = $this->thresholds->get_threshold(
            $base_product_id,
            $variation_id
        );

        if ($threshold === null) {
            $threshold = (int) get_option('woolsn_default_threshold', 5);
        }

        if ($stock_quantity > $threshold) {
            return;
        }

        // Evita notifiche duplicate: verifica se è già stata inviata una notifica
        // per questo prodotto/variation con questo stock nelle ultime 2 ore
        $notification_key = sprintf(
            'woolsn_notified_%d_%d_%d',
            $base_product_id,
            $variation_id,
            $stock_quantity
        );

        // Se esiste già un transient per questa combinazione, non inviare di nuovo
        if (get_transient($notification_key) !== false) {
            return;
        }

        // Invia la notifica
        $this->notifier->send_low_stock_email($product, $stock_quantity, $threshold);

        // Imposta un transient per 2 ore per evitare duplicati
        set_transient($notification_key, true, 2 * HOUR_IN_SECONDS);

        /** @var LoggerService|null $logger */
        $logger = $this->plugin->service(LoggerService::class);
        if ($logger instanceof LoggerService) {
            $logger->info(
                sprintf(
                    'Notification dispatched for product #%1$d - stock %2$d (threshold %3$d)',
                    $base_product_id,
                    $stock_quantity,
                    $threshold
                )
            );
        }
    }

    private function resolve_notifier(Plugin $plugin): NotificationService
    {
        $service = $plugin->service(NotificationService::class);
        if ($service instanceof NotificationService) {
            return $service;
        }

        return new NotificationService($plugin);
    }
}

