<?php

namespace App\Services;

use App\Models\Order;
use App\Models\OrderLog;
use Illuminate\Support\Facades\DB;

class OrderSyncService
{
    protected $wooService;

    public function updateOrder(Order $order, array $data, $userId = null)
    {
        DB::beginTransaction();

        try {
            // Get old data for comparison
            $oldData = $order->only(['billing', 'shipping', 'status']);

            // Update local order FIRST - this should ALWAYS succeed
            $order->update($data);
            $order->date_modified = now();
            $order->save();

            // OPTIMIZATION: Only store fields that actually changed (reduces storage by 70-90%)
            $changedOldData = [];
            $changedNewData = [];

            foreach ($data as $key => $newValue) {
                $oldValue = $oldData[$key] ?? null;

                // For nested arrays (billing, shipping), only store changed sub-fields
                if (is_array($newValue) && is_array($oldValue)) {
                    $nestedOld = [];
                    $nestedNew = [];
                    foreach ($newValue as $nestedKey => $nestedNewValue) {
                        $nestedOldValue = $oldValue[$nestedKey] ?? null;
                        if ($nestedOldValue != $nestedNewValue) {
                            $nestedOld[$nestedKey] = $nestedOldValue;
                            $nestedNew[$nestedKey] = $nestedNewValue;
                        }
                    }
                    if (!empty($nestedOld)) {
                        $changedOldData[$key] = $nestedOld;
                        $changedNewData[$key] = $nestedNew;
                    }
                } else {
                    // For simple fields, only store if changed
                    if ($oldValue != $newValue) {
                        $changedOldData[$key] = $oldValue;
                        $changedNewData[$key] = $newValue;
                    }
                }
            }

            // Only create log if there are actual changes
            if (!empty($changedOldData)) {
                OrderLog::create([
                    'order_id' => $order->id,
                    'user_id' => $userId,
                    'action' => 'update',
                    'old_data' => $changedOldData,
                    'new_data' => $changedNewData
                ]);
            }

            // Commit local changes FIRST before attempting WooCommerce sync
            DB::commit();

            // Try to sync with WooCommerce if applicable (but don't fail if this doesn't work)
            if ($order->store && $order->woo_order_id) {
                try {
                    // Prepare WooCommerce update data
                    $wooData = [];

                    if (isset($data['billing'])) {
                        $wooData['billing'] = $data['billing'];
                    }

                    if (isset($data['shipping'])) {
                        $wooData['shipping'] = $data['shipping'];
                    }

                    if (isset($data['status'])) {
                        $wooData['status'] = $data['status'];
                    }

                    // Update in WooCommerce
                    $this->wooService = new WooCommerceService($order->store);
                    $result = $this->wooService->updateOrder($order->woo_order_id, $wooData);

                    if (!$result) {
                        // Log the sync failure but don't fail the local update
                        \Log::warning('WooCommerce sync failed but local order was updated', [
                            'order_id' => $order->id,
                            'woo_order_id' => $order->woo_order_id,
                            'store_id' => $order->store_id
                        ]);
                    } else {
                        \Log::info('Order successfully synced to WooCommerce', [
                            'order_id' => $order->id,
                            'woo_order_id' => $order->woo_order_id
                        ]);
                    }
                } catch (\Exception $wooException) {
                    // Log WooCommerce sync error but don't fail the local update
                    \Log::error('WooCommerce sync exception but local order was updated', [
                        'order_id' => $order->id,
                        'woo_order_id' => $order->woo_order_id,
                        'error' => $wooException->getMessage()
                    ]);
                }
            }

            // Refresh the order model to get latest data
            $order->refresh();

            return true;

        } catch (\Exception $e) {
            DB::rollBack();
            throw $e;
        }
    }
}