<?php

namespace App\Http\Controllers\Api\GoPoints;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Order;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Log;

class OrdersController extends Controller
{
    /**
     * 6.1 Crear Orden (POST /api/gopoints/orders)
     */
    public function create(Request $request)
    {
        try {
            $data = json_decode($request->getContent(), true) ?? [];

            // Validación campaña
            $campaign = Str::lower(trim($data['Campaign'] ?? ''));
            if ($campaign !== 'gopoints') {
                return response()->json([
                    'Status'    => 400,
                    'Message'   => 'Campaña no reconocida',
                    'CodeError' => 'INVALID_CAMPAIGN',
                    'Exception' => null,
                ], 400, [], JSON_UNESCAPED_UNICODE);
            }

            // Validaciones mínimas de payload
            if (empty($data['Customer']['Name'] ?? '') || empty($data['Customer']['Email'] ?? '')) {
                return response()->json([
                    'Status'    => 422,
                    'Message'   => 'Datos de cliente incompletos',
                    'CodeError' => 'INVALID_CUSTOMER',
                    'Exception' => null,
                ], 422, [], JSON_UNESCAPED_UNICODE);
            }

            if (empty($data['Items']) || !is_array($data['Items'])) {
                return response()->json([
                    'Status'    => 422,
                    'Message'   => 'Debe incluir al menos un ítem',
                    'CodeError' => 'INVALID_ITEMS',
                    'Exception' => null,
                ], 422, [], JSON_UNESCAPED_UNICODE);
            }

            // Suma de ítems y verificación de Total (tolerancia mínima)
            $calc = 0.0;
            $items = [];
            foreach ($data['Items'] as $it) {
                $sku = (string)($it['Sku'] ?? '');
                $qty = (int)($it['Quantity'] ?? 0);
                $price = (float)($it['Price'] ?? 0);
                if ($sku === '' || $qty <= 0 || $price < 0) {
                    return response()->json([
                        'Status'    => 422,
                        'Message'   => 'Ítem inválido (Sku/Quantity/Price)',
                        'CodeError' => 'INVALID_ITEM_ROW',
                        'Exception' => null,
                    ], 422, [], JSON_UNESCAPED_UNICODE);
                }
                $calc += $qty * $price;
                $items[] = ['Sku' => $sku, 'Quantity' => $qty, 'Price' => $price];
            }

            $total = (float)($data['Total'] ?? 0);
            if ($total <= 0 || abs($calc - $total) > 0.5) {
                return response()->json([
                    'Status'    => 422,
                    'Message'   => 'Total no coincide con la suma de ítems',
                    'CodeError' => 'TOTAL_MISMATCH',
                    'Exception' => null,
                ], 422, [], JSON_UNESCAPED_UNICODE);
            }

            // Generar ID de orden del proveedor
            $providerOrderId = (string) Str::uuid();
            $createdAt = now();

            // Persistir (ajusta columnas a tu migración)
            $order = Order::create([
                'order_id'         => $providerOrderId,
                'campaign_id'      => 'GoPoints',
                'customer_name'    => $data['Customer']['Name'],
                'customer_email'   => $data['Customer']['Email'],
                'status'           => 'CREATED',
                'total'            => $total,
                'discount'         => (float)($data['Discount'] ?? 0),
                'shipping'         => (float)($data['ShippingValue'] ?? 0),
                'payment_method'   => 'GoPoints',
                'products'         => json_encode($items, JSON_UNESCAPED_UNICODE),
                'shipping_address' => json_encode($data['Shipping'] ?? [], JSON_UNESCAPED_UNICODE),
                'created_at'       => $createdAt,
            ]);

            Log::info('✅ GoPoints Order Created', ['order_id' => $order->order_id]);

            // Respuesta en formato manual
            return response()->json([
                'Status'          => 200,
                'Message'         => 'Orden creada correctamente',
                'CodeError'       => '',
                'Exception'       => null,
                'Parameters'      => [
                    'Campaign' => 'GoPoints',
                    'Customer' => [
                        'Name'  => (string)$data['Customer']['Name'],
                        'Email' => (string)$data['Customer']['Email'],
                    ],
                    'Items'   => $items,
                    'Total'   => $total,
                ],
                'ProviderOrderId' => $providerOrderId,
                'CreatedAt'       => $createdAt->toIso8601String(),
            ], 200, [], JSON_UNESCAPED_UNICODE);

        } catch (\Throwable $e) {
            Log::error('❌ Error creating GoPoints order: '.$e->getMessage());

            return response()->json([
                'Status'    => 500,
                'Message'   => 'Error creando la orden',
                'CodeError' => 'ORDER_CREATION_ERROR',
                'Exception' => $e->getMessage(),
            ], 500, [], JSON_UNESCAPED_UNICODE);
        }
    }

    /**
     * 6.2 Confirmar/Cancelar Orden (POST /api/gopoints/orders/confirm)
     */
    public function confirm(Request $request)
    {
        try {
            $data = json_decode($request->getContent(), true) ?? [];

            $campaign = Str::lower(trim($data['Campaign'] ?? ''));
            if ($campaign !== 'gopoints') {
                return response()->json([
                    'Status'    => 400,
                    'Message'   => 'Campaña no reconocida',
                    'CodeError' => 'INVALID_CAMPAIGN',
                    'Exception' => null,
                ], 400, [], JSON_UNESCAPED_UNICODE);
            }

            $providerOrderId = (string)($data['ProviderOrderId'] ?? '');
            $confirmed = (bool)($data['Confirmed'] ?? false);

            if ($providerOrderId === '') {
                return response()->json([
                    'Status'    => 422,
                    'Message'   => 'ProviderOrderId es requerido',
                    'CodeError' => 'INVALID_PROVIDER_ORDER_ID',
                    'Exception' => null,
                ], 422, [], JSON_UNESCAPED_UNICODE);
            }

            $order = Order::where('order_id', $providerOrderId)->first();
            if (!$order) {
                return response()->json([
                    'Status'    => 404,
                    'Message'   => 'Pedido no encontrado',
                    'CodeError' => 'ORDER_NOT_FOUND',
                    'Exception' => null,
                ], 404, [], JSON_UNESCAPED_UNICODE);
            }

            $order->status = $confirmed ? 'CONFIRMED' : 'CANCELLED';
            $order->confirmation_date = now();
            $order->save();

            Log::info('✅ GoPoints Order Confirmed', [
                'order_id' => $order->order_id,
                'status'   => $order->status,
            ]);

            return response()->json([
                'Status'    => 200,
                'Message'   => $confirmed ? 'Orden confirmada correctamente' : 'Orden cancelada correctamente',
                'CodeError' => '',
                'Exception' => null,
                'Parameters'=> [
                    'Campaign'        => 'GoPoints',
                    'ProviderOrderId' => $providerOrderId,
                    'Confirmed'       => $confirmed,
                ],
                'Order'     => [
                    'ProviderOrderId'  => $order->order_id,
                    'Status'           => $order->status,
                    'ConfirmationDate' => $order->confirmation_date->toIso8601String(),
                ],
            ], 200, [], JSON_UNESCAPED_UNICODE);

        } catch (\Throwable $e) {
            Log::error('❌ Error confirming GoPoints order: '.$e->getMessage());

            return response()->json([
                'Status'    => 500,
                'Message'   => 'Error confirmando la orden',
                'CodeError' => 'ORDER_CONFIRMATION_ERROR',
                'Exception' => $e->getMessage(),
            ], 500, [], JSON_UNESCAPED_UNICODE);
        }
    }
}
