<?php
/**
 * Product Event Handler for Magento Sync
 *
 * @category    PortalPeople
 * @package     Magento
 * @author      Portal People Development Team
 * @copyright   Copyright (c) 2025 Portal People (https://portalpeople.co.uk)
 */

namespace PortalPeople\magento\handlers;

use Yii;
use yii\base\Event;
use yii\db\ActiveRecord;

/**
 * Product Event Handler
 * 
 * Handles product-related events and triggers Magento synchronization
 */
class ProductEventHandler
{
    /**
     * Handle product update events
     * 
     * @param Event $event
     */
    public static function handleProductUpdate($event)
    {
        /** @var ActiveRecord $product */
        $product = $event->sender;

        // Only handle product models (check if it has required fields)
        if (!self::isProductModel($product)) {
            return;
        }

        try {
            // Get the Magento sync component
            $syncComponent = Yii::$app->magentoSync;
            
            if (!$syncComponent) {
                Yii::warning('Magento sync component not configured', 'magento-sync');
                return;
            }

            // Get changed attributes
            $changedFields = array_keys($product->getDirtyAttributes());
            
            // Check if any price fields changed
            $priceFields = $syncComponent->priceFields;
            $priceChanges = array_intersect($changedFields, $priceFields);

            if (!empty($priceChanges)) {
                Yii::info("Price changes detected for product {$product->sku}: " . implode(', ', $priceChanges), 'magento-sync');
                
                // Sync only price changes for better performance
                $syncComponent->syncPriceChanges($product, $changedFields);
            } elseif (self::hasRelevantChanges($changedFields, $syncComponent->fieldMapping)) {
                Yii::info("Relevant changes detected for product {$product->sku}: " . implode(', ', $changedFields), 'magento-sync');
                
                // Sync entire product for other changes
                $syncComponent->syncProduct($product, 'update');
            }

        } catch (\Exception $e) {
            Yii::error("Error handling product update for {$product->sku}: " . $e->getMessage(), 'magento-sync');
        }
    }

    /**
     * Handle product creation events
     * 
     * @param Event $event
     */
    public static function handleProductCreate($event)
    {
        /** @var ActiveRecord $product */
        $product = $event->sender;

        // Only handle product models
        if (!self::isProductModel($product)) {
            return;
        }

        try {
            // Get the Magento sync component
            $syncComponent = Yii::$app->magentoSync;
            
            if (!$syncComponent) {
                Yii::warning('Magento sync component not configured', 'magento-sync');
                return;
            }

            Yii::info("New product created, syncing to Magento: {$product->sku}", 'magento-sync');
            
            // Sync new product to Magento
            $syncComponent->syncProduct($product, 'create');

        } catch (\Exception $e) {
            Yii::error("Error handling product creation for {$product->sku}: " . $e->getMessage(), 'magento-sync');
        }
    }

    /**
     * Handle product deletion events
     * 
     * @param Event $event
     */
    public static function handleProductDelete($event)
    {
        /** @var ActiveRecord $product */
        $product = $event->sender;

        // Only handle product models
        if (!self::isProductModel($product)) {
            return;
        }

        try {
            // Get the Magento sync component
            $syncComponent = Yii::$app->magentoSync;
            
            if (!$syncComponent) {
                Yii::warning('Magento sync component not configured', 'magento-sync');
                return;
            }

            Yii::info("Product deleted, disabling in Magento: {$product->sku}", 'magento-sync');
            
            // Disable product in Magento (soft delete)
            $syncComponent->syncProduct($product, 'delete');

        } catch (\Exception $e) {
            Yii::error("Error handling product deletion for {$product->sku}: " . $e->getMessage(), 'magento-sync');
        }
    }

    /**
     * Check if the model is a product model
     * 
     * @param ActiveRecord $model
     * @return bool
     */
    protected static function isProductModel($model)
    {
        // Check if model has typical product fields
        return $model->hasAttribute('sku') && 
               ($model->hasAttribute('name') || 
                $model->hasAttribute('title') || 
                $model->hasAttribute('product_name'));
    }

    /**
     * Check if any relevant fields have changed
     * 
     * @param array $changedFields
     * @param array $fieldMapping
     * @return bool
     */
    protected static function hasRelevantChanges($changedFields, $fieldMapping)
    {
        $relevantFields = array_keys($fieldMapping);
        return !empty(array_intersect($changedFields, $relevantFields));
    }

    /**
     * Handle stock/inventory changes
     * 
     * @param Event $event
     */
    public static function handleStockUpdate($event)
    {
        /** @var ActiveRecord $stockItem */
        $stockItem = $event->sender;

        try {
            // Get the associated product
            $product = null;
            
            // Try different common relationships
            if ($stockItem->hasAttribute('product_id')) {
                $product = $stockItem->product;
            } elseif ($stockItem->hasAttribute('sku')) {
                // Find product by SKU
                $productClass = self::getProductClass();
                if ($productClass) {
                    $product = $productClass::findOne(['sku' => $stockItem->sku]);
                }
            }

            if (!$product) {
                return;
            }

            // Get the Magento sync component
            $syncComponent = Yii::$app->magentoSync;
            
            if (!$syncComponent) {
                return;
            }

            // Get changed fields
            $changedFields = array_keys($stockItem->getDirtyAttributes());
            
            // Check if quantity or stock status changed
            if (in_array('qty', $changedFields) || in_array('quantity', $changedFields) || 
                in_array('is_in_stock', $changedFields) || in_array('in_stock', $changedFields)) {
                
                Yii::info("Stock changes detected for product {$product->sku}", 'magento-sync');
                
                // Update stock in Magento
                $qty = $stockItem->qty ?? $stockItem->quantity ?? 0;
                $inStock = $stockItem->is_in_stock ?? $stockItem->in_stock ?? ($qty > 0);
                
                Yii::$app->magentoClient->updateProductStock($product->sku, $qty, $inStock);
            }

        } catch (\Exception $e) {
            Yii::error("Error handling stock update: " . $e->getMessage(), 'magento-sync');
        }
    }

    /**
     * Get the product model class name
     * 
     * @return string|null
     */
    protected static function getProductClass()
    {
        // Try common product model class names
        $possibleClasses = [
            'app\models\Product',
            'app\models\Products',
            'common\models\Product',
            'common\models\Products'
        ];

        foreach ($possibleClasses as $class) {
            if (class_exists($class)) {
                return $class;
            }
        }

        return null;
    }
}