<?php

namespace Meliconnect\Meliconnect\Core;

if (! defined('ABSPATH')) {
    exit; // Exit if accessed directly
}

use Meliconnect\Meliconnect\Core\Helpers\Helper;
use Meliconnect\Meliconnect\Core\Helpers\MeliconMeli;
use Meliconnect\Meliconnect\Core\Helpers\SyncHashHelper;
use Meliconnect\Meliconnect\Core\Models\UserConnection;
use Meliconnect\Meliconnect\Modules\Importer\Services\ProductDataFacade;
use Meliconnect\Meliconnect\Modules\Importer\Services\WooCommerceProductAdapter;
use Meliconnect\Meliconnect\Modules\Importer\Services\WooCommerceProductCreationService;

class ApiManager
{


    public function __construct()
    {
        // Registrar la ruta de la API al inicializar el API REST
        add_action('rest_api_init', array($this, 'register_routes'));
    }

    /**
     * Registrar las rutas de la API
     */
    public function register_routes()
    {
        register_rest_route(
            'meliconnect/v1',
            '/update_domain',
            array(
                'methods'             => 'POST',
                'callback'            => array($this, 'meliconnect_update_domains'),
                'permission_callback' => '__return_true',
            )
        );

        register_rest_route(
            'meliconnect/v1',
            '/status',
            array(
                'methods'             => 'GET',
                'callback'            => array($this, 'meliconnect_plugin_status'),
                'permission_callback' => '__return_true',
            )
        );

        register_rest_route(
            'meliconnect/v1',
            '/sync/product',
            array(
                'methods'               => 'POST',
                'callback'              => array($this, 'meliconnect_sync_product_callback'),
                //'permission_callback' => [ ApiAuth::class, 'authorize' ],
                'permission_callback' => '__return_true',
            )
        );
    }

    public static function meliconnect_sync_stock_callback($request, $meli_payload = null)
    {
        $meli_listing_id = sanitize_text_field($request->get_param('meli_listing_id'));

        Helper::logData(
            "Stock sync callback: {$meli_listing_id} payload=" . json_encode($meli_payload),
            'sync_product_callback'
        );

        // Ejemplo: podrías usar esto en el futuro
        $quantity = $meli_payload['locations'][0]['quantity'] ?? null;


        (new self())->markMeliChanges(
            $meli_listing_id,
            ['stock'],
            'stock'
        );

        return rest_ensure_response([
            'success'  => true,
            'type'     => 'stock',
            'quantity' => $quantity
        ]);
    }



    private function upsertFromMeli($meli_listing_id)
    {
        global $wpdb;

        $table = $wpdb->prefix . 'meliconnect_sync_state';

        // ya existe?
        $existing = $wpdb->get_var($wpdb->prepare(
            "SELECT id FROM {$table} WHERE meli_item_id = %s LIMIT 1",
            $meli_listing_id
        ));

        if ($existing) return;

        // intentar encontrar producto Woo
        $woo_product_id = Helper::meliconnect_find_product_by_listing_id($meli_listing_id);

        if (!$woo_product_id) {
            Helper::logData("No Woo product for {$meli_listing_id}", 'sync_product_callback');
            return;
        }

        $seller_id      = get_post_meta($woo_product_id, 'meliconnect_meli_seller_id', true);

        $wpdb->insert($table, [
            'woo_product_id' => $woo_product_id ?: null,
            'meli_item_id'   => $meli_listing_id,
            'meli_seller_id' => $seller_id,

            'sync_status' => 'pending',
            'needs_sync'  => 1,
            'sync_type'   => 'full',
            'direction'   => 'meli_to_woo',
            'source'      => 'meli',
            'priority'    => 10,

            'created_at' => current_time('mysql'),
            'updated_at' => current_time('mysql'),
        ]);

        Helper::logData("UPSERT FROM MELI {$meli_listing_id}", 'sync_product_callback');
    }

    public static function meliconnect_sync_product_callback($request)
    {
        $meli_listing_id = sanitize_text_field($request->get_param('meli_listing_id'));
        $seller_id       = sanitize_text_field($request->get_param('seller_id'));
        $topic           = sanitize_text_field($request->get_param('topic'));
        $meli_payload    = $request->get_param('meli_payload');
        $meli_payload    = is_array($meli_payload) ? $meli_payload : null;



        if (empty($meli_listing_id) || empty($seller_id)) {
            return new \WP_Error(
                'invalid_payload',
                'Missing parameters',
                ['status' => 400]
            );
        }

        Helper::logData('------ START SYNC PRODUCT CALLBACK ------', 'sync_product_callback');

        // ===============================
        // SETTINGS
        // ===============================
        $syncOptions = Helper::getMeliconnectOptions('sync');

        if (!(new self())->shouldHandleTopic($topic, $syncOptions)) {

            Helper::logData(
                "Sync skipped by settings: topic={$topic} DISABLED",
                'sync_product_callback'
            );

            return rest_ensure_response([
                'success' => true,
                'skipped' => true,
            ]);
        } else {
            Helper::logData(
                "Sync enabled: topic={$topic}",
                'sync_product_callback'
            );
        }

        Helper::logData(
            "Webhook received: listing={$meli_listing_id} seller={$seller_id} topic={$topic}",
            'sync_product_callback'
        );

        // ===============================
        // ROUTING POR TOPIC
        // ===============================

        // PRICE
        if (in_array($topic, ['items_prices', 'prices'], true)) {

            return self::meliconnect_sync_price_callback($request);
        }

        // STOCK
        $stockTopics = ['items_stock', 'stock_locations', 'stock-locations', 'inventory'];

        if (in_array($topic, $stockTopics, true)) {

            return self::meliconnect_sync_stock_callback($request, $meli_payload);
        }

        // ORDERS → FULL SYNC
        if ($topic === 'orders_v2') {
            return self::enqueueFullSync($meli_listing_id);
        }

        // PRODUCT
        $productTopics = ['items', 'user-products-families'];

        if (!in_array($topic, $productTopics, true)) {
            Helper::logData(
                "Sync skipped: unsupported topic {$topic}",
                'sync_product_callback'
            );

            return rest_ensure_response([
                'success' => true,
                'skipped' => true,
            ]);
        }



        // ===============================
        // IMPORTADOR (Todo el producto)
        // ===============================
        try {
            Helper::logData(
                "Sync product: {$meli_listing_id}",
                'sync_product_callback'
            );

            $woo_product_id = Helper::meliconnect_find_product_by_listing_id($meli_listing_id);

            $autoCreate = ($syncOptions['meliconnect_sync_create_product'] ?? 'false') === 'true';

            if (!$woo_product_id && !$autoCreate) {

                return rest_ensure_response([
                    'success' => true,
                    'skipped' => true,
                ]);
            }

            $template_id = $woo_product_id
                ? get_post_meta($woo_product_id, 'meliconnect_asoc_template_id', true)
                : null;

            $wasExistingProduct = !empty($woo_product_id);

            if (!$wasExistingProduct && $autoCreate) {

                Helper::logData(
                    "AUTO CREATE DETECTED listing={$meli_listing_id}",
                    'sync_product_callback'
                );
            }

            $facade = new ProductDataFacade(
                new WooCommerceProductAdapter(),
                new WooCommerceProductCreationService()
            );

            $createdOrUpdated = $facade->importAndCreateProduct(
                $meli_listing_id,
                $seller_id,
                $template_id,
                $woo_product_id
            );

            if (!$wasExistingProduct && $autoCreate) {

                $newWooId = Helper::meliconnect_find_product_by_listing_id($meli_listing_id);

                Helper::logData(
                    "AUTO CREATED PRODUCT listing={$meli_listing_id} woo_id={$newWooId}",
                    'sync_product_callback'
                );
            }

            Helper::logData(
                "Sync product result: {$createdOrUpdated}",
                'sync_product_callback'
            );

            (new self())->upsertFromMeli($meli_listing_id);

            return rest_ensure_response([
                'success' => true
            ]);
        } catch (\Throwable $e) {

            Helper::logData(
                "Sync product failed: {$e->getMessage()}",
                'sync_product_callback'
            );

            return new \WP_Error('sync_failed', 'Error syncing product', ['status' => 500]);
        }
    }

    private function shouldHandleTopic($topic, $options)
    {
        $map = [
            'price' => ['items_prices', 'prices'],
            'stock' => ['items_stock', 'inventory', 'stock_locations', 'stock-locations'],
            'orders' => ['orders_v2'],
            'product' => ['items', 'user-products-families']
        ];

        foreach ($map as $type => $topics) {

            if (in_array($topic, $topics, true)) {

                $keyMap = [
                    'price'   => 'meliconnect_sync_on_price_changes',
                    'stock'   => 'meliconnect_sync_on_stock_locations',
                    'orders'  => 'meliconnect_sync_on_orders',
                    'product' => 'meliconnect_sync_on_product_changes',
                ];

                return $this->isEnabled($options, 'meliconnect_sync_enable_auto_sync')
                    && $this->isEnabled($options, $keyMap[$type]);
            }
        }

        return false;
    }

    private function isEnabled($options, $key)
    {
        return isset($options[$key]) && $options[$key] === 'true';
    }

    public static function meliconnect_sync_price_callback($request)
    {
        $meli_listing_id = sanitize_text_field($request->get_param('meli_listing_id'));

        Helper::logData(
            "Price sync callback: {$meli_listing_id}",
            'sync_product_callback'
        );

        (new self())->markMeliChanges(
            $meli_listing_id,
            ['price'],
            'price'
        );

        return rest_ensure_response([
            'success' => true,
            'type'    => 'price'
        ]);
    }

    private static function enqueueFullSync($meli_listing_id)
    {
        Helper::logData(
            "Order trigger → FULL sync {$meli_listing_id}",
            'sync_product_callback'
        );

        (new self())->markMeliChanges(
            $meli_listing_id,
            ['price', 'stock', 'status'],
            'full'
        );

        return rest_ensure_response([
            'success' => true,
            'type'    => 'full'
        ]);
    }

    private function markMeliChanges($meli_listing_id, array $fields, $syncType = 'partial')
    {
        global $wpdb;

        $table = $wpdb->prefix . 'meliconnect_sync_state';

        // ===============================
        // Ensure sync_state exists
        // ===============================
        $items = $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM {$table} WHERE meli_item_id = %s",
            $meli_listing_id
        ));

        if (empty($items)) {

            Helper::logData(
                "No sync_state for {$meli_listing_id} → creating",
                'sync_product_callback'
            );

            $this->upsertFromMeli($meli_listing_id);

            $items = $wpdb->get_results($wpdb->prepare(
                "SELECT * FROM {$table} WHERE meli_item_id = %s",
                $meli_listing_id
            ));

            if (empty($items)) {

                Helper::logData(
                    "Failed to create sync_state {$meli_listing_id}",
                    'sync_product_callback'
                );

                return;
            }
        }

        // ===============================
        // Priority
        // ===============================
        $fieldPriorities = array_map(
            fn($field) => SyncHashHelper::resolvePriority($field),
            $fields
        );

        $maxFieldPriority = !empty($fieldPriorities)
            ? max($fieldPriorities)
            : 0;

        // ===============================
        // Update items
        // ===============================
        foreach ($items as $item) {

            $existingChanges = json_decode($item->changes, true);
            $existingChanges = is_array($existingChanges)
                ? $existingChanges
                : [];

            foreach ($fields as $field) {
                $existingChanges[$field] = true;
            }

            $priority = max(
                $maxFieldPriority,
                (int) $item->priority
            );

            $wpdb->update(
                $table,
                [
                    'sync_status' => 'pending',
                    'needs_sync'  => 1,
                    'direction'   => 'meli_to_woo',
                    'source'      => 'meli',
                    'sync_type'   => $syncType,
                    'changes'     => json_encode($existingChanges),
                    'priority'    => $priority,
                    'updated_at'  => current_time('mysql')
                ],
                ['id' => $item->id]
            );

            Helper::logData(
                "Queued {$meli_listing_id} sync={$syncType} changes=" . json_encode($fields),
                'sync_product_callback'
            );
        }

        Helper::logData(
            '------ END SYNC PRODUCT CALLBACK ------',
            'sync_product_callback'
        );
    }





    // Callback del endpoint
    public function meliconnect_plugin_status($request)
    {
        $plugin_slug = 'meliconnect/meliconnect.php';
        include_once ABSPATH . 'wp-admin/includes/plugin.php';

        return array(
            'plugin'             => 'meliconnect',
            'active'             => is_plugin_active($plugin_slug),
            'version'            => defined('MELICONNECT_VERSION') ? MELICONNECT_VERSION : 'unknown',
            'wp_version'         => get_bloginfo('version'),
            'site_url'           => get_site_url(),
            'woocommerce_active' => class_exists('WooCommerce'),
        );
    }

    /**
     * Callback para procesar el dominio
     */
    public function meliconnect_update_domains($request)
    {
        $users_in_domain = $request->get_param('users_in_domain');

        if (! is_array($users_in_domain)) {
            Helper::logData('Received bad parameters in request: ' . wp_json_encode($request->get_params()), 'users_in_domain');

            return rest_ensure_response(
                array(
                    'message' => 'Missing required parameters.',
                    'success' => false,
                )
            );
        }

        Helper::logData('Received connected users: ' . wp_json_encode($users_in_domain) . '', 'users_in_domain');

        UserConnection::update_users_connections($users_in_domain);

        // Responder con el estado de la acción
        return rest_ensure_response(
            array(
                'message' => 'Users in domain updated successfully.',
                'success' => true,
            )
        );
    }
}
