<?php

namespace App\Http\Controllers\API\Admin;

use App\Http\Controllers\Controller;
use App\Models\Order;
use App\Models\Restaurant;
use App\Models\DeliveryBoy;
use App\Models\Delivery;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class OrderManagementController extends Controller
{
    public function index(Request $request)
    {
        try {
            $query = Order::select('id', 'order_number', 'user_id', 'restaurant_id', 'status', 'payment_status', 'payment_method', 'subtotal', 'delivery_fee', 'tax', 'total', 'delivery_address', 'created_at')
                ->with([
                    'user:id,name,phone',
                    'restaurant:id,name',
                    'delivery:id,order_id,delivery_boy_id,status',
                    'delivery.deliveryBoy:id,full_name,phone'
                ]);
            
            // Apply filters
            if ($request->status && $request->status !== 'all') {
                $query->where('status', $request->status);
            }
            
            if ($request->restaurant_id) {
                $query->where('restaurant_id', $request->restaurant_id);
            }
            
            if ($request->date_from) {
                $query->whereDate('created_at', '>=', $request->date_from);
            }
            
            if ($request->date_to) {
                $query->whereDate('created_at', '<=', $request->date_to);
            }
            
            if ($request->search) {
                $query->where(function($q) use ($request) {
                    $q->where('order_number', 'like', '%' . $request->search . '%')
                      ->orWhereHas('user', function($userQuery) use ($request) {
                          $userQuery->where('name', 'like', '%' . $request->search . '%');
                      });
                });
            }
            
            $orders = $query->latest()->paginate($request->per_page ?? 20);
            
            return response()->json([
                'success' => true,
                'data' => $orders
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to load orders'
            ], 500);
        }
    }

    public function show($id)
    {
        try {
            $order = Order::with([
                'user', 
                'restaurant', 
                'items.product', 
                'delivery.deliveryBoy'
            ])->findOrFail($id);
            
            return response()->json([
                'success' => true,
                'data' => $order
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Order not found'
            ], 404);
        }
    }

    public function updateStatus(Request $request, $id)
    {
        $order = Order::findOrFail($id);
        
        $request->validate([
            'status' => 'required|in:pending,accepted,preparing,ready,picked_up,delivered,cancelled'
        ]);
         
        if ($order->status === $request->status) {
            return response()->json([
                'success' => true,
                'message' => 'Order is already in this status',
                'data' => $order->fresh(['user', 'restaurant', 'items.product', 'delivery.deliveryBoy'])
            ]);
        }
       
        request()->merge(['bypass_validation' => true]);
        $order->status = $request->status;
        $order->save();
        
        return response()->json([
            'success' => true,
            'message' => 'Order status updated successfully',
            'data' => $order->fresh(['user', 'restaurant', 'items.product', 'delivery.deliveryBoy'])
        ]);
    }

    public function assignDeliveryBoy(Request $request, $id)
    {
        try {
            $order = Order::with('restaurant')->findOrFail($id);
            
            $request->validate([
                'delivery_boy_id' => 'required|exists:delivery_boys,id'
            ]);
            
            $delivery = Delivery::updateOrCreate(
                ['order_id' => $order->id],
                [
                    'delivery_boy_id' => $request->delivery_boy_id,
                    'status' => 'assigned',
                    'assigned_at' => now(),
                    'pickup_latitude' => $order->restaurant->latitude ?? 0,
                    'pickup_longitude' => $order->restaurant->longitude ?? 0,
                    'pickup_address' => $order->restaurant->address ?? '',
                    'delivery_latitude' => $order->delivery_latitude ?? 0,
                    'delivery_longitude' => $order->delivery_longitude ?? 0,
                    'delivery_address' => $order->delivery_address ?? '',
                    'distance_km' => $order->distance_km ?? 0,
                    'delivery_fee' => $order->delivery_fee ?? 0
                ]
            );
            
            return response()->json([
                'success' => true,
                'message' => 'Delivery boy assigned successfully',
                'data' => $delivery->load('deliveryBoy')
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 500);
        }
    }

    public function cancelOrder(Request $request, $id)
    {
        try {
            $order = Order::findOrFail($id);
            
            if (in_array($order->status, ['delivered', 'cancelled'])) {
                return response()->json([
                    'success' => false,
                    'message' => 'Cannot cancel this order'
                ], 400);
            }
            
            $order->update([
                'status' => 'cancelled',
                'cancelled_at' => now(),
                'cancellation_reason' => $request->reason ?? 'Cancelled by admin'
            ]);
            
            return response()->json([
                'success' => true,
                'message' => 'Order cancelled successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to cancel order'
            ], 500);
        }
    }

    public function getDashboardStats()
    {
        try {
            $today = Carbon::today();
            $yesterday = Carbon::yesterday();
            
            // Basic stats
            $totalOrders = Order::count();
            $todayOrders = Order::whereDate('created_at', $today)->count();
            $yesterdayOrders = Order::whereDate('created_at', $yesterday)->count();
            
            $totalRevenue = Order::where('payment_status', 'paid')->sum('total');
            $todayRevenue = Order::where('payment_status', 'paid')->whereDate('created_at', $today)->sum('total');
            $yesterdayRevenue = Order::where('payment_status', 'paid')->whereDate('created_at', $yesterday)->sum('total');
            
            // Calculate trends
            $ordersTrend = $yesterdayOrders > 0 ? (($todayOrders - $yesterdayOrders) / $yesterdayOrders) * 100 : 0;
            $revenueTrend = $yesterdayRevenue > 0 ? (($todayRevenue - $yesterdayRevenue) / $yesterdayRevenue) * 100 : 0;
            
            // Status breakdown
            $statusBreakdown = Order::select('status', DB::raw('count(*) as count'))
                ->groupBy('status')
                ->get()
                ->pluck('count', 'status');
            
            // Recent orders
            $recentOrders = Order::with(['user', 'restaurant'])
                ->latest()
                ->limit(10)
                ->get();
            
            // Top restaurants
            $topRestaurants = Restaurant::withCount(['orders' => function($q) use ($today) {
                    $q->whereDate('created_at', $today);
                }])
                ->withSum(['orders' => function($q) use ($today) {
                    $q->whereDate('created_at', $today)->where('payment_status', 'paid');
                }], 'total')
                ->having('orders_count', '>', 0)
                ->orderBy('orders_count', 'desc')
                ->limit(5)
                ->get();
            
            // Available delivery boys
            $availableDeliveryBoys = DeliveryBoy::where('status', 'available')
                ->with('user')
                ->get();
            
            return response()->json([
                'success' => true,
                'data' => [
                    'stats' => [
                        'total_orders' => $totalOrders,
                        'today_orders' => $todayOrders,
                        'orders_trend' => round($ordersTrend, 1),
                        'total_revenue' => $totalRevenue,
                        'today_revenue' => $todayRevenue,
                        'revenue_trend' => round($revenueTrend, 1),
                        'pending_orders' => Order::where('status', 'pending')->count(),
                        'active_orders' => Order::whereIn('status', ['accepted', 'preparing', 'ready', 'picked_up'])->count(),
                        'delivered_today' => Order::where('status', 'delivered')->whereDate('created_at', $today)->count(),
                        'cancelled_today' => Order::where('status', 'cancelled')->whereDate('created_at', $today)->count(),
                    ],
                    'status_breakdown' => $statusBreakdown,
                    'recent_orders' => $recentOrders,
                    'top_restaurants' => $topRestaurants,
                    'available_delivery_boys' => $availableDeliveryBoys
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to load dashboard stats'
            ], 500);
        }
    }

    public function getOrdersByRestaurant()
    {
        try {
            $restaurants = Restaurant::with(['orders' => function($query) {
                $query->with(['user', 'orderItems.product'])
                      ->latest()
                      ->limit(50);
            }])->get();
            
            return response()->json([
                'success' => true,
                'data' => $restaurants
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to load orders by restaurant'
            ], 500);
        }
    }

    public function getRestaurantOrders(Request $request, $restaurantId)
    {
        try {
            $restaurant = Restaurant::findOrFail($restaurantId);
            
            $query = Order::with(['user', 'items.product', 'delivery.deliveryBoy'])
                ->where('restaurant_id', $restaurantId);
            
            if ($request->status && $request->status !== 'all') {
                $query->where('status', $request->status);
            }
            
            if ($request->date_from) {
                $query->whereDate('created_at', '>=', $request->date_from);
            }
            
            if ($request->date_to) {
                $query->whereDate('created_at', '<=', $request->date_to);
            }
            
            if ($request->search) {
                $query->where(function($q) use ($request) {
                    $q->where('order_number', 'like', '%' . $request->search . '%')
                      ->orWhereHas('user', function($userQuery) use ($request) {
                          $userQuery->where('name', 'like', '%' . $request->search . '%')
                                    ->orWhere('phone', 'like', '%' . $request->search . '%');
                      });
                });
            }
            
            $perPage = $request->per_page ?? 20;
            $orders = $query->latest()->paginate($perPage);
            
            $stats = [
                'total_orders' => Order::where('restaurant_id', $restaurantId)->count(),
                'total_revenue' => Order::where('restaurant_id', $restaurantId)
                    ->where('payment_status', 'paid')->sum('total'),
                'pending_orders' => Order::where('restaurant_id', $restaurantId)
                    ->where('status', 'pending')->count(),
                'delivered_orders' => Order::where('restaurant_id', $restaurantId)
                    ->where('status', 'delivered')->count(),
            ];
            
            return response()->json([
                'success' => true,
                'data' => [
                    'restaurant' => $restaurant,
                    'orders' => $orders,
                    'stats' => $stats
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to load restaurant orders'
            ], 500);
        }
    }

    public function bulkUpdateStatus(Request $request)
    {
        try {
            $request->validate([
                'order_ids' => 'required|array',
                'status' => 'required|in:pending,accepted,preparing,ready,picked_up,delivered,cancelled'
            ]);
            
            Order::whereIn('id', $request->order_ids)
                ->update(['status' => $request->status]);
            
            return response()->json([
                'success' => true,
                'message' => 'Orders updated successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to update orders'
            ], 500);
        }
    }

    public function getAnalytics(Request $request)
    {
        try {
            $days = $request->get('days', 7);
            $startDate = Carbon::now()->subDays($days);
            
            // Daily orders
            $dailyOrders = Order::select(
                DB::raw('DATE(created_at) as date'),
                DB::raw('COUNT(*) as orders'),
                DB::raw('SUM(total) as revenue')
            )
            ->where('created_at', '>=', $startDate)
            ->groupBy(DB::raw('DATE(created_at)'))
            ->orderBy('date')
            ->get();
            
            // Hourly distribution
            $hourlyOrders = Order::select(
                DB::raw('HOUR(created_at) as hour'),
                DB::raw('COUNT(*) as orders')
            )
            ->where('created_at', '>=', $startDate)
            ->groupBy(DB::raw('HOUR(created_at)'))
            ->orderBy('hour')
            ->get();
            
            return response()->json([
                'success' => true,
                'data' => [
                    'daily_orders' => $dailyOrders,
                    'hourly_orders' => $hourlyOrders,
                    'period' => [
                        'days' => $days,
                        'start_date' => $startDate->format('Y-m-d'),
                        'end_date' => Carbon::now()->format('Y-m-d')
                    ]
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to load analytics'
            ], 500);
        }
    }

    public function getRestaurants()
    {
        try {
            $restaurants = Restaurant::select('id', 'name', 'status')
                ->where('status', 'approved')
                ->get();
            
            return response()->json([
                'success' => true,
                'data' => $restaurants
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to load restaurants'
            ], 500);
        }
    }

    public function getDeliveryBoys()
    {
        try {
            $deliveryBoys = DeliveryBoy::select('id', 'full_name', 'phone', 'status', 'rating', 'total_deliveries')
                ->whereIn('status', ['online', 'offline'])
                ->get();
            
            return response()->json([
                'success' => true,
                'data' => $deliveryBoys
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to load delivery boys'
            ], 500);
        }
    }

    public function exportOrders(Request $request)
    {
        try {
            $query = Order::with(['user', 'restaurant', 'items.product', 'delivery.deliveryBoy']);
            
            // If specific order IDs are provided, export only those
            if ($request->order_ids) {
                $orderIds = is_array($request->order_ids) ? $request->order_ids : explode(',', $request->order_ids);
                $query->whereIn('id', $orderIds);
            } else {
                // Otherwise apply filters
                if ($request->status) {
                    $query->where('status', $request->status);
                }
                
                if ($request->restaurant_id) {
                    $query->where('restaurant_id', $request->restaurant_id);
                }
                
                if ($request->date_from) {
                    $query->whereDate('created_at', '>=', $request->date_from);
                }
                
                if ($request->date_to) {
                    $query->whereDate('created_at', '<=', $request->date_to);
                }
            }
            
            $orders = $query->latest()->get();
            
            $filename = 'orders_' . date('Y-m-d_His') . '.xls';
            
            $headers = [
                'Content-Type' => 'application/vnd.ms-excel',
                'Content-Disposition' => 'attachment; filename="' . $filename . '"',
                'Cache-Control' => 'max-age=0',
            ];
            
            $callback = function() use ($orders) {
                echo "<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:x='urn:schemas-microsoft-com:office:excel' xmlns='http://www.w3.org/TR/REC-html40'>";
                echo "<head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'></head>";
                echo "<body><table border='1'>";
                echo "<tr style='background-color: #ff6b35; color: white; font-weight: bold;'>";
                echo "<th>Order #</th>";
                echo "<th>Customer Name</th>";
                echo "<th>Customer Phone</th>";
                echo "<th>Restaurant</th>";
                echo "<th>Delivery Address</th>";
                echo "<th>Items</th>";
                echo "<th>Subtotal (Rs)</th>";
                echo "<th>Delivery Fee (Rs)</th>";
                echo "<th>Tax (Rs)</th>";
                echo "<th>Total (Rs)</th>";
                echo "<th>Status</th>";
                echo "<th>Payment Method</th>";
                echo "<th>Payment Status</th>";
                echo "<th>Delivery Boy</th>";
                echo "<th>Order Date</th>";
                echo "<th>Notes</th>";
                echo "</tr>";
                
                foreach ($orders as $order) {
                    $items = $order->items->map(function($item) {
                        return $item->product->name . ' x' . $item->quantity;
                    })->implode(', ');
                    
                    echo "<tr>";
                    echo "<td>" . htmlspecialchars($order->order_number) . "</td>";
                    echo "<td>" . htmlspecialchars($order->user->name ?? 'N/A') . "</td>";
                    echo "<td>" . htmlspecialchars($order->user->phone ?? $order->delivery_phone ?? 'N/A') . "</td>";
                    echo "<td>" . htmlspecialchars($order->restaurant->name ?? 'N/A') . "</td>";
                    echo "<td>" . htmlspecialchars($order->delivery_address ?? 'N/A') . "</td>";
                    echo "<td>" . htmlspecialchars($items) . "</td>";
                    echo "<td style='text-align: right;'>" . number_format($order->subtotal ?? 0, 2) . "</td>";
                    echo "<td style='text-align: right;'>" . number_format($order->delivery_fee ?? 0, 2) . "</td>";
                    echo "<td style='text-align: right;'>" . number_format($order->tax ?? 0, 2) . "</td>";
                    echo "<td style='text-align: right; font-weight: bold;'>" . number_format($order->total, 2) . "</td>";
                    echo "<td>" . htmlspecialchars(ucfirst(str_replace('_', ' ', $order->status))) . "</td>";
                    echo "<td>" . htmlspecialchars(ucfirst($order->payment_method)) . "</td>";
                    echo "<td>" . htmlspecialchars(ucfirst($order->payment_status ?? 'pending')) . "</td>";
                    echo "<td>" . htmlspecialchars($order->delivery->deliveryBoy->user->name ?? 'Not Assigned') . "</td>";
                    echo "<td>" . $order->created_at->format('Y-m-d H:i:s') . "</td>";
                    echo "<td>" . htmlspecialchars($order->notes ?? '') . "</td>";
                    echo "</tr>";
                }
                
                echo "</table></body></html>";
            };
            
            return response()->stream($callback, 200, $headers);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to export orders'
            ], 500);
        }
    }
}