<?php

namespace App\Services;

use App\Models\Order;
use App\Models\OrderItem;
use App\Models\ProductVariant;
use App\Models\Coupon;
use Illuminate\Support\Facades\DB;
use Exception;

class OrderService
{
    public function calculateDeliveryFee(string $method, int $totalItems): int
    {
        if ($method === 'ena_coach') {
            return $totalItems < 10 ? 20000 : 50000; // 20000 cents = KES 200, 50000 cents = KES 500
        } elseif ($method === 'wells_fargo') {
            return $totalItems < 10 ? 50000 : 75000; // 50000 cents = KES 500, 75000 cents = KES 750
        }
        return 0;
    }

    public function createOrder(array $data): Order
    {
        return DB::transaction(function () use ($data) {
            $userId = $data['user_id'] ?? null;
            $items = $data['items'];
            $deliveryMethod = $data['delivery_method'];
            $deliveryLocation = $data['delivery_location'];
            $guestName = $data['guest_name'] ?? null;
            $guestPhone = $data['guest_phone'] ?? null;
            $couponCode = $data['coupon_code'] ?? null;

            $subtotal = 0;
            $totalItems = 0;
            $processedItems = [];

            foreach ($items as $item) {
                $variant = ProductVariant::with('product')->findOrFail($item['variant_id']);
                
                if ($variant->stock_qty < $item['quantity']) {
                    throw new Exception("Insufficient stock for product: {$variant->product->name} ({$variant->size} - {$variant->color})");
                }

                $price = $variant->price_override !== null ? $variant->price_override : $variant->product->base_price;
                $linePrice = $price * $item['quantity'];
                
                $subtotal += $linePrice;
                $totalItems += $item['quantity'];

                $processedItems[] = [
                    'product_id' => $variant->product_id,
                    'variant_id' => $variant->id,
                    'quantity' => $item['quantity'],
                    'unit_price' => $price,
                    'variant_model' => $variant
                ];
            }

            $deliveryFee = $this->calculateDeliveryFee($deliveryMethod, $totalItems);

            $discountAmount = 0;
            if ($couponCode) {
                $coupon = Coupon::active()->where('code', $couponCode)->first();
                if ($coupon && $coupon->isValidForAmount($subtotal)) {
                    $discountAmount = $coupon->calculateDiscount($subtotal);
                    $coupon->increment('used_count');
                } else {
                    throw new Exception("Invalid or expired coupon code.");
                }
            }

            $total = $subtotal + $deliveryFee - $discountAmount;
            if ($total < 0) {
                $total = 0;
            }

            $order = Order::create([
                'user_id' => $userId,
                'guest_name' => $guestName,
                'guest_phone' => $guestPhone,
                'delivery_location' => $deliveryLocation,
                'delivery_method' => $deliveryMethod,
                'delivery_fee' => $deliveryFee,
                'subtotal' => $subtotal,
                'discount_amount' => $discountAmount,
                'total' => $total,
                'coupon_code' => $couponCode,
                'status' => 'pending',
            ]);

            foreach ($processedItems as $pItem) {
                OrderItem::create([
                    'order_id' => $order->id,
                    'product_id' => $pItem['product_id'],
                    'variant_id' => $pItem['variant_id'],
                    'quantity' => $pItem['quantity'],
                    'unit_price' => $pItem['unit_price'],
                ]);

                $pItem['variant_model']->decrement('stock_qty', $pItem['quantity']);
            }

            return $order;
        });
    }
}
