<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\Delivery;
use App\Models\DeliveryBoy;
use App\Models\Order;
use App\Models\Wallet;
use App\Models\WalletTransaction;
use Illuminate\Http\Request;

class DeliveryController extends Controller
{
    public function assignDelivery(Request $request, $orderId)
    {
        $order = Order::with('restaurant')->findOrFail($orderId);
        
        $candidates = DeliveryBoy::where('status', 'available')
            ->where('is_active', true)
            ->whereNotNull('current_latitude')
            ->whereNotNull('current_longitude')
            ->get();

        $deliveryBoy = null;
        if ($candidates->isNotEmpty()) {
            $deliveryBoy = $candidates->sortBy(function ($boy) use ($order) {
                $dx = (float)$order->restaurant->latitude - (float)$boy->current_latitude;
                $dy = (float)$order->restaurant->longitude - (float)$boy->current_longitude;
                return ($dx * $dx) + ($dy * $dy);
            })->first();
        }

        if (!$deliveryBoy) {
            $deliveryBoy = DeliveryBoy::where('status', 'available')
                ->where('is_active', true)
                ->first();
        }

        if (!$deliveryBoy) {
            return response()->json(['message' => 'No delivery boy available'], 400);
        }

        $boyPercent = (float)$deliveryBoy->commission_percentage;
        $adminPercent = (float)config('commission.admin_delivery_commission_percent', 0);
        $deliveryFee = (float)$order->delivery_fee;

        if ($adminPercent > 0) {
            $deliveryBoyEarning = round($deliveryFee * ($boyPercent / 100), 2);
            $platformCommission = round($deliveryFee * ($adminPercent / 100), 2);
        } else {
            $deliveryBoyEarning = round($deliveryFee * ($boyPercent / 100), 2);
            $platformCommission = round($deliveryFee - $deliveryBoyEarning, 2);
        }

        $delivery = Delivery::create([
            'order_id' => $order->id,
            'delivery_boy_id' => $deliveryBoy->id,
            'status' => 'assigned',
            'pickup_latitude' => $order->restaurant->latitude,
            'pickup_longitude' => $order->restaurant->longitude,
            'pickup_address' => $order->restaurant->address,
            'delivery_latitude' => $order->delivery_latitude,
            'delivery_longitude' => $order->delivery_longitude,
            'delivery_address' => $order->delivery_address,
            'distance_km' => $order->distance_km,
            'delivery_fee' => $order->delivery_fee,
            'delivery_boy_earning' => $deliveryBoyEarning,
            'platform_commission' => $platformCommission,
            'assigned_at' => now(),
        ]);

        $deliveryBoy->update(['status' => 'busy']);

        return response()->json($delivery->load('deliveryBoy'));
    }

    public function acceptDelivery($id)
    {
        $delivery = Delivery::findOrFail($id);
        $delivery->update([
            'status' => 'accepted',
            'accepted_at' => now(),
        ]);

        return response()->json($delivery);
    }

    public function rejectDelivery(Request $request, $id)
    {
        $delivery = Delivery::findOrFail($id);
        $delivery->update([
            'status' => 'rejected',
            'rejection_reason' => $request->reason,
        ]);
        if ($delivery->deliveryBoy) {
            $delivery->deliveryBoy->update(['status' => 'available']);
        }
        return response()->json($delivery);
    }

    public function updateStatus(Request $request, $id)
    {
        $delivery = Delivery::findOrFail($id);
        
        $delivery->update(['status' => $request->status]);

        if ($request->status === 'picked_up') {
            $delivery->update(['picked_up_at' => now()]);
            $delivery->order->update(['status' => 'picked_up']);
        } elseif ($request->status === 'delivered') {
            $delivery->update(['delivered_at' => now()]);
            $delivery->order->update(['status' => 'delivered', 'delivered_at' => now()]);
            
            $deliveryBoy = $delivery->deliveryBoy;
            $deliveryBoy->increment('total_earnings', $delivery->delivery_boy_earning);
            $deliveryBoy->increment('total_deliveries');
            $deliveryBoy->update(['status' => 'available']);

            $wallet = Wallet::firstOrCreate(['user_id' => $deliveryBoy->user_id], ['balance' => 0]);
            $wallet->increment('balance', $delivery->delivery_boy_earning);
            WalletTransaction::create([
                'wallet_id' => $wallet->id,
                'type' => 'credit',
                'amount' => $delivery->delivery_boy_earning,
                'balance_after' => $wallet->balance,
                'description' => "Earning for delivery #{$delivery->id}",
                'reference_type' => 'Delivery',
                'reference_id' => $delivery->id,
            ]);
        }

        return response()->json($delivery);
    }

    public function trackDelivery($orderId)
    {
        $delivery = Delivery::with(['order', 'deliveryBoy'])
            ->where('order_id', $orderId)
            ->firstOrFail();

        return response()->json($delivery);
    }
}
