<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\UpdateOrderStatusRequest;
use App\Jobs\ProcessShipmentJob;
use App\Models\Carrier;
use App\Models\Order;
use App\Models\Shipment;
use App\Services\LedgerService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use Illuminate\View\View;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Route;
use Illuminate\Validation\ValidationException;
use PDF;

class OrderController extends Controller
{
    public function index(Request $request): View
    {
        $allowedPerPage = [10, 20, 50, 100];
        $perPage = (int) $request->input('per_page', 10);
        if (!in_array($perPage, $allowedPerPage, true)) {
            $perPage = 10;
        }

        $query = Order::with('user');

        // Handle merged cancelled/failed filter
        if ($request->filled('filter') && $request->filter === 'cancelled_failed') {
            $query->where(function ($mergedFilterQuery) {
                $mergedFilterQuery->where('status', Order::STATUS_CANCELLED)
                    ->orWhere('payment_status', Order::PAYMENT_FAILED);
            });
        } else {
            if ($request->filled('status')) {
                $query->where('status', $request->status);
            }

            if ($request->filled('payment_status')) {
                $query->where('payment_status', $request->payment_status);
            }
        }

        if ($request->filled('source')) {
            $query->where('source', $request->source);
        }

        // Order ID filter
        if ($request->filled('order_id')) {
            $normalizedOrderId = preg_replace('/\D+/', '', (string) $request->order_id);
            if (!empty($normalizedOrderId)) {
                $query->where('id', (int) $normalizedOrderId);
            } else {
                // Invalid order id input should not match any records
                $query->whereRaw('1 = 0');
            }
        }

        // Customer phone filter (registered user mobile or snapshot phone fields)
        if ($request->filled('customer_phone')) {
            $customerPhone = trim((string) $request->customer_phone);
            $query->where(function ($phoneQuery) use ($customerPhone) {
                $phoneQuery->whereHas('user', function ($userQuery) use ($customerPhone) {
                    $userQuery->where('mobile', 'like', "%{$customerPhone}%");
                })->orWhere('address_snapshot->mobile', 'like', "%{$customerPhone}%")
                  ->orWhere('address_snapshot->phone', 'like', "%{$customerPhone}%")
                  ->orWhere('address_snapshot->contact', 'like', "%{$customerPhone}%");
            });
        }

        // Date filter
        if ($request->filled('date_filter')) {
            $dateFilter = $request->date_filter;
            
            switch ($dateFilter) {
                case 'today':
                    $query->whereDate('created_at', today());
                    break;
                    
                case 'yesterday':
                    $query->whereDate('created_at', today()->subDay());
                    break;
                    
                case 'last_7_days':
                    $query->where('created_at', '>=', now()->subDays(7));
                    break;
                    
                case 'last_month':
                    $query->where('created_at', '>=', now()->subMonth());
                    break;
                    
                case 'last_year':
                    $query->where('created_at', '>=', now()->subYear());
                    break;
                    
                case 'custom':
                    if ($request->filled('date_from')) {
                        $query->whereDate('created_at', '>=', $request->date_from);
                    }
                    if ($request->filled('date_to')) {
                        $query->whereDate('created_at', '<=', $request->date_to);
                    }
                    break;
            }
        }

        $orders = $query->latest()->paginate($perPage)->withQueryString();

        // Get status counts for filter pills
        $statusCounts = $this->getStatusCounts($request ?? null);

        return view('admin.orders.index', compact('orders', 'statusCounts', 'perPage', 'allowedPerPage'));
    }

    /**
     * Get counts for each status filter
     */
    private function getStatusCounts($request): array
    {
        $baseQuery = Order::query();
        if ($request && $request->filled('source')) {
            $baseQuery->where('source', $request->source);
        }
        
        if ($request->filled('date_filter')) {
            $dateFilter = $request->date_filter;
            
            switch ($dateFilter) {
                case 'today':
                    $baseQuery->whereDate('created_at', today());
                    break;
                    
                case 'yesterday':
                    $baseQuery->whereDate('created_at', today()->subDay());
                    break;
                    
                case 'last_7_days':
                    $baseQuery->where('created_at', '>=', now()->subDays(7));
                    break;
                    
                case 'last_month':
                    $baseQuery->where('created_at', '>=', now()->subMonth());
                    break;
                    
                case 'last_year':
                    $baseQuery->where('created_at', '>=', now()->subYear());
                    break;
                    
                case 'custom':
                    if ($request->filled('date_from')) {
                        $baseQuery->whereDate('created_at', '>=', $request->date_from);
                    }
                    if ($request->filled('date_to')) {
                        $baseQuery->whereDate('created_at', '<=', $request->date_to);
                    }
                    break;
            }
        }

        return [
            'all_orders'        => (clone $baseQuery)->count(),
            'awaiting_payment'  => (clone $baseQuery)->where('status', Order::STATUS_AWAITING_PAYMENT)->count(),
            'order_placed'      => (clone $baseQuery)->where('status', Order::STATUS_PLACED)->count(),
            'order_confirmed'   => (clone $baseQuery)->where('status', Order::STATUS_CONFIRMED)->count(),
            'order_packed'      => (clone $baseQuery)->where('status', Order::STATUS_PACKED)->count(),
            'shipment_created'  => (clone $baseQuery)->where('status', Order::STATUS_AWAITING_PICKUP)->count(),
            'shipped'           => (clone $baseQuery)->where('status', Order::STATUS_SHIPPED)->count(),
            'completed'         => (clone $baseQuery)->where('status', Order::STATUS_DELIVERED)->count(),
            'cancelled_failed'  => (clone $baseQuery)
                ->where(function ($mergedCountQuery) {
                    $mergedCountQuery->where('status', Order::STATUS_CANCELLED)
                        ->orWhere('payment_status', Order::PAYMENT_FAILED);
                })->count(),
        ];
    }

    public function show(Order $order): View
    {
        try {
            $order->load('items.product', 'user', 'coupon', 'staff');
            
            // Load shipments if table exists
            if (Schema::hasTable('shipments')) {
                $order->load('shipments.carrier');
            }
        } catch (\Exception $e) {
            // If shipments table doesn't exist or relationship fails, continue without it
            Log::warning('Failed to load shipments for order: ' . $e->getMessage());
        }

        // Get enabled carriers for shipment initiation
        $carriers = collect();
        try {
            if (Schema::hasTable('carriers')) {
                $carriers = Carrier::enabled()->get();
            }
        } catch (\Exception $e) {
            // Carriers table might not exist
        }

        return view('admin.orders.show', compact('order', 'carriers'));
    }

    public function printInvoice(Order $order): View
    {
        $order->loadMissing('items.product', 'user', 'staff');

        return view('admin.orders.thermal_invoice', [
            'order' => $order,
            'autoPrint' => true,
        ]);
    }

    /**
     * Get status sequence order for forward-only validation
     */
    private function getStatusSequence(): array
    {
        return [
            Order::STATUS_AWAITING_PAYMENT => 1,
            Order::STATUS_PLACED => 2,
            Order::STATUS_CONFIRMED => 3,
            Order::STATUS_PACKED => 4,
            Order::STATUS_AWAITING_PICKUP => 5,
            Order::STATUS_SHIPPED => 6,
            Order::STATUS_DELIVERED => 7,
            // cancelled and returned are special cases
        ];
    }

    /**
     * Check if status change is forward (or special case)
     */
    private function isStatusForward(string $currentStatus, string $newStatus): bool
    {
        // Special cases: cancelled can be set from any status, returned from delivered
        if ($newStatus === Order::STATUS_CANCELLED) {
            return true; // Can always cancel
        }
        if ($newStatus === Order::STATUS_RETURNED && $currentStatus === Order::STATUS_DELIVERED) {
            return true; // Can return from delivered
        }
        
        $sequence = $this->getStatusSequence();
        $currentOrder = $sequence[$currentStatus] ?? 0;
        $newOrder = $sequence[$newStatus] ?? 0;
        
        return $newOrder > $currentOrder;
    }

    public function updateStatus(UpdateOrderStatusRequest $request, Order $order): RedirectResponse
    {
        $newStatus = $request->validated('status');
        $currentStatus = $order->status;
        $user = auth()->user();

        // Skip closed-day check for admins or users with reopen permission
        if (!$user->isAdmin() && !$user->can('reports.day-ledger.reopen')) {
            try {
                app(LedgerService::class)->assertDayOpen($order->created_at->toDateString());
            } catch (ValidationException $e) {
                $message = $e->errors()['date'][0] ?? 'This day is closed. Reopen it before updating order status.';
                return redirect()->back()->with('error', $message);
            }
        }

        // Check if status change is backward (for non-admin users)
        if (!$user->isAdmin()) {
            if (!$this->isStatusForward($currentStatus, $newStatus)) {
                return redirect()->back()->with('error', 'Order status can only be moved forward.');
            }
        }

        $order->update([
            'status' => $newStatus,
        ]);

        return redirect()->back()->with('success', 'Order status updated successfully!');
    }

    public function updateAddress(Request $request, Order $order): JsonResponse|RedirectResponse
    {
        // Skip closed-day check for admins or users with reopen permission
        $user = auth()->user();
        if (!$user || (!$user->isAdmin() && !$user->can('reports.day-ledger.reopen'))) {
            try {
                app(LedgerService::class)->assertDayOpen($order->created_at->toDateString());
            } catch (ValidationException $e) {
                $message = $e->errors()['date'][0] ?? 'This day is closed. Reopen it before editing order details.';
                if ($request->expectsJson()) {
                    return response()->json([
                        'success' => false,
                        'message' => $message,
                    ], 422);
                }

                return redirect()->back()->with('error', $message);
            }
        }

        // Check if order status allows editing
        $allowedStatuses = [Order::STATUS_AWAITING_PAYMENT, Order::STATUS_PLACED, Order::STATUS_CONFIRMED, Order::STATUS_PACKED];
        if (!in_array($order->status, $allowedStatuses)) {
            if ($request->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Address can only be edited for orders with status: placed, confirmed, or packed.',
                ], 403);
            }
            return redirect()->back()->with('error', 'Address can only be edited for orders with status: placed, confirmed, or packed.');
        }

        // Validate address fields
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'mobile' => 'required|string|max:15',
            'line1' => 'required|string|max:255',
            'line2' => 'nullable|string|max:255',
            'city' => 'required|string|max:255',
            'state' => 'required|string|max:255',
            'pin' => 'required|string|regex:/^\d{6}$/',
            'country' => 'nullable|string|max:255',
        ], [
            'name.required' => 'Name is required.',
            'mobile.required' => 'Mobile number is required.',
            'line1.required' => 'Address line 1 is required.',
            'city.required' => 'City is required.',
            'state.required' => 'State is required.',
            'pin.required' => 'Pincode is required.',
            'pin.regex' => 'Pincode must be exactly 6 digits.',
        ]);

        // Get current address snapshot and preserve any additional fields
        $currentSnapshot = $order->address_snapshot ?? [];
        
        // Build updated address snapshot
        $addressSnapshot = [
            'name' => $validated['name'],
            'mobile' => $validated['mobile'],
            'line1' => $validated['line1'],
            'line2' => $validated['line2'] ?? null,
            'city' => $validated['city'],
            'state' => $validated['state'],
            'pin' => $validated['pin'],
        ];

        // Preserve country and IDs if they exist
        if (isset($currentSnapshot['country'])) {
            $addressSnapshot['country'] = $validated['country'] ?? $currentSnapshot['country'];
        } elseif (isset($validated['country'])) {
            $addressSnapshot['country'] = $validated['country'];
        }

        if (isset($currentSnapshot['country_id'])) {
            $addressSnapshot['country_id'] = $currentSnapshot['country_id'];
        }
        if (isset($currentSnapshot['state_id'])) {
            $addressSnapshot['state_id'] = $currentSnapshot['state_id'];
        }
        if (isset($currentSnapshot['city_id'])) {
            $addressSnapshot['city_id'] = $currentSnapshot['city_id'];
        }

        // Update order address snapshot
        $order->update([
            'address_snapshot' => $addressSnapshot,
        ]);

        if ($request->expectsJson()) {
            return response()->json([
                'success' => true,
                'message' => 'Shipping address updated successfully!',
                'address' => $addressSnapshot,
            ]);
        }

        return redirect()->back()->with('success', 'Shipping address updated successfully!');
    }

    /**
     * Get carriers list for shipment initiation modal
     */
    public function initiateShipment(Order $order): JsonResponse
    {
        // Check permission
        $user = auth()->user();
        if (!$user->can('manage shipping') && !$user->isAdmin() && !$user->isStaff()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        // Check if order is packed
        if ($order->status !== Order::STATUS_PACKED) {
            return response()->json(['error' => 'Order must be in packed status'], 400);
        }

        // Check if shipment already exists
        if ($order->shipments()->exists()) {
            return response()->json(['error' => 'Shipment already exists for this order'], 400);
        }

        // Get enabled carriers (include process_type for front-end)
        $carriers = Carrier::enabled()->get()->map(function ($carrier) {
            return [
                'id' => $carrier->id,
                'name' => $carrier->name,
                'slug' => $carrier->slug,
                'process_type' => $carrier->process_type ?? \App\Models\Carrier::PROCESS_TYPE_AUTOMATIC,
                'config_schema' => $carrier->config_schema ?? [],
            ];
        });

        return response()->json([
            'success' => true,
            'carriers' => $carriers,
        ]);
    }

    /**
     * Check delivery availability for a carrier and pincode
     */
    public function checkDeliveryAvailability(Request $request, Order $order): JsonResponse
    {
        try {
            // Check permission
            $user = auth()->user();
            if (!$user->can('manage shipping') && !$user->isAdmin() && !$user->isStaff()) {
                return response()->json(['error' => 'Unauthorized'], 403);
            }

            // Validate carrier_id
            $validated = $request->validate([
                'carrier_id' => 'required|exists:carriers,id',
            ]);

            $carrier = Carrier::findOrFail($validated['carrier_id']);

            // Manual carriers: no API check, assume available
            if ($carrier->isManual()) {
                return response()->json([
                    'available' => true,
                    'message' => 'Manual carrier – tracking will be entered on the order.',
                    'carrier' => $carrier->slug,
                ]);
            }

            // Get pincode from order address
            $address = $order->address_snapshot;
            if (empty($address['pin'])) {
                return response()->json([
                    'error' => 'Order address does not have a pincode',
                ], 400);
            }

            $pincode = $address['pin'];

            // Get carrier service and check availability
            $carrierService = \App\Services\Carriers\CarrierServiceFactory::makeFromModel($carrier);
            $result = $carrierService->checkDeliveryAvailability($pincode);

            return response()->json([
                'available' => $result['available'],
                'message' => $result['message'],
                'carrier' => $carrier->slug,
            ]);
        } catch (\Illuminate\Validation\ValidationException $e) {
            return response()->json([
                'error' => 'Validation failed',
                'errors' => $e->errors(),
            ], 422);
        } catch (\Exception $e) {
            Log::error('Failed to check delivery availability', [
                'order_id' => $order->id,
                'error' => $e->getMessage(),
            ]);

            return response()->json([
                'error' => 'Failed to check delivery availability: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Store shipment and dispatch job
     */
    public function storeShipment(Request $request, Order $order): JsonResponse|RedirectResponse
    {
        try {
            // Check permission
            $user = auth()->user();
            if (!$user->can('manage shipping') && !$user->isAdmin() && !$user->isStaff()) {
                if ($request->expectsJson()) {
                    return response()->json(['error' => 'Unauthorized'], 403);
                }
                return redirect()->back()->with('error', 'Unauthorized');
            }

            // Check if shipments table exists
            if (!Schema::hasTable('shipments')) {
                if ($request->expectsJson()) {
                    return response()->json(['error' => 'Shipments table does not exist. Please run migrations.'], 500);
                }
                return redirect()->back()->with('error', 'Shipments table does not exist. Please run migrations.');
            }

            // Check if order is packed
            if ($order->status !== Order::STATUS_PACKED) {
                if ($request->expectsJson()) {
                    return response()->json(['error' => 'Order must be in packed status'], 400);
                }
                return redirect()->back()->with('error', 'Order must be in packed status');
            }

            // Delete any failed shipments first
            try {
                $order->shipments()->where('status', Shipment::STATUS_FAILED)->delete();
            } catch (\Exception $e) {
                Log::warning('Failed to delete failed shipments: ' . $e->getMessage());
            }

            // Check if shipment already exists (excluding deleted ones)
            try {
                if ($order->shipments()->exists()) {
                    if ($request->expectsJson()) {
                        return response()->json(['error' => 'Shipment already exists for this order'], 400);
                    }
                    return redirect()->back()->with('error', 'Shipment already exists for this order');
                }
            } catch (\Exception $e) {
                // Relationship might fail if table structure is wrong, continue anyway
                Log::warning('Failed to check existing shipments: ' . $e->getMessage());
            }

            // Validate carrier_id first
            $data = $request->validate([
                'carrier_id' => 'required|exists:carriers,id',
                'tracking_number' => 'nullable|string|max:255',
            ]);

            $carrier = Carrier::findOrFail($data['carrier_id']);

            if (!$carrier->enabled) {
                if ($request->expectsJson()) {
                    return response()->json(['error' => 'Carrier is disabled'], 400);
                }
                return redirect()->back()->with('error', 'Carrier is disabled');
            }

            if ($carrier->isManual()) {
                $request->validate(['tracking_number' => 'required|string|max:255']);
                $trackingNumber = trim($data['tracking_number'] ?? '');

                $shipment = Shipment::create([
                    'order_id' => $order->id,
                    'carrier_id' => $carrier->id,
                    'tracking_id' => $trackingNumber,
                    'status' => Shipment::STATUS_CREATED,
                    'metadata' => null,
                ]);

                $order->update([
                    'status' => Order::STATUS_SHIPPED,
                    'delhivery_awb' => $trackingNumber,
                ]);

                if ($request->expectsJson()) {
                    return response()->json([
                        'success' => true,
                        'message' => 'Manual shipment recorded successfully!',
                        'shipment_id' => $shipment->id,
                    ]);
                }
                return redirect()->back()->with('success', 'Manual shipment recorded successfully!');
            }

            // Automatic: handle form_data
            $formData = $request->input('form_data');
            if (is_string($formData) && !empty($formData)) {
                $decoded = json_decode($formData, true);
                $formData = (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) ? $decoded : [];
            }
            $data['form_data'] = is_array($formData) ? $formData : [];

            // Create shipment record
            $shipment = Shipment::create([
                'order_id' => $order->id,
                'carrier_id' => $carrier->id,
                'status' => Shipment::STATUS_PENDING,
                'metadata' => !empty($data['form_data']) ? $data['form_data'] : null,
            ]);

            (new ProcessShipmentJob($shipment, $data['form_data'] ?? []))->execute();

            if ($request->expectsJson()) {
                return response()->json([
                    'success' => true,
                    'message' => 'Shipment initiated successfully!',
                    'shipment_id' => $shipment->id,
                ]);
            }

            return redirect()->back()->with('success', 'Shipment initiated successfully! Processing in background...');
        } catch (\Illuminate\Validation\ValidationException $e) {
            if ($request->expectsJson()) {
                return response()->json([
                    'error' => 'Validation failed',
                    'errors' => $e->errors(),
                ], 422);
            }
            return redirect()->back()->withErrors($e->errors())->withInput();
        } catch (\Exception $e) {
            Log::error('Failed to create shipment', [
                'order_id' => $order->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);

            if ($request->expectsJson()) {
                return response()->json([
                    'error' => 'Failed to create shipment: ' . $e->getMessage(),
                ], 500);
            }

            return redirect()->back()->with('error', 'Failed to create shipment: ' . $e->getMessage());
        }
    }

    /**
     * API endpoint for orders with cursor pagination and KPIs
     */
    public function apiIndex(Request $request): JsonResponse
    {
        // Validate inputs
        $validated = $request->validate([
            'status' => 'nullable|string|in:all,placed,processing,shipped,delivered,cancelled,returned',
            'per_page' => 'nullable|integer|min:1|max:100',
            'cursor' => 'nullable|string',
        ]);

        $status = $validated['status'] ?? 'placed';
        $perPage = $validated['per_page'] ?? 15;

        // Build base query
        $query = Order::with(['user', 'items.product:id,name,image_path'])
            ->select('orders.*');

        // Apply status filter
        $query->byStatus($status);

        // Apply cursor pagination
        if ($request->filled('cursor')) {
            $cursor = json_decode(base64_decode($request->cursor), true);
            if (isset($cursor['id'])) {
                $query->where('id', '<', $cursor['id']);
            }
        }

        // Order by id desc for cursor pagination
        $query->orderBy('id', 'desc');

        // Get orders
        $orders = $query->limit($perPage + 1)->get();

        // Check if there are more results
        $hasMore = $orders->count() > $perPage;
        if ($hasMore) {
            $orders = $orders->take($perPage);
        }

        // Prepare next cursor
        $nextCursor = null;
        if ($hasMore && $orders->isNotEmpty()) {
            $lastOrder = $orders->last();
            $nextCursor = base64_encode(json_encode(['id' => $lastOrder->id]));
        }

        // Format orders for response
        $formattedOrders = $orders->map(function ($order) {
            return [
                'id' => $order->id,
                'order_number' => '#' . $order->id,
                'created_at' => $order->created_at->toIso8601String(),
                'status' => $order->status,
                'status_label' => $order->status_label,
                'status_badge_class' => $order->status_badge_class,
                'items_count' => $order->items->count(),
                'total_payable' => number_format($order->total_payable, 2, '.', ''),
                'payment_status' => $order->payment_status,
                'payment_method' => $order->payment_method,
                'source' => $order->source ?? 'online',
                'user' => [
                    'id' => $order->user->id,
                    'name' => $order->user->name,
                    'mobile' => $order->user->mobile,
                ],
                'address_snapshot' => $order->address_snapshot ?? [],
                'items' => $order->items->take(3)->map(function ($item) {
                    $product = $item->product;
                    if (!$product) {
                        // Product was deleted, use item name as fallback
                        return [
                            'product' => [
                                'id' => null,
                                'name' => $item->name ?? 'N/A',
                                'image_path' => null,
                            ],
                        ];
                    }
                    return [
                        'product' => [
                            'id' => $product->id,
                            'name' => $product->name ?? $item->name ?? 'N/A',
                            'image_path' => $product->image_path ?? null,
                        ],
                    ];
                })->filter(function ($item) {
                    // Keep items even if product is deleted (show item name)
                    return true;
                }),
            ];
        });

        // Calculate KPIs based on status filter
        $kpis = $this->calculateKpis($status);

        return response()->json([
            'data' => $formattedOrders,
            'next_cursor' => $nextCursor,
            'has_more' => $hasMore,
            'meta' => [
                'per_page' => $perPage,
                'status' => $status,
            ],
            'kpis' => $kpis,
        ]);
    }

    public function orderLabel($id){
        $order = Order::find(decrypt($id));
        // $order = $orderDetail->order;
        
        $pdf = PDF::loadView('admin.orders.label', [
            'order' => $order,
        ], [], [
            'format' =>  [100, 150],
            'orientation' => 'P',
            'margin_left' => 1,
            'margin_right' => 1,
            'margin_top' => 4,
            'margin_bottom' => 1,
            'dpi' => 300,
        ]);

        $fileName = "label-{$order->code}.pdf";

        return $pdf->stream($fileName);
    }

    /**
     * Calculate KPIs for orders (Shopify-style)
     */
    private function calculateKpis(string $status): array
    {
        $today = now()->startOfDay();
        $baseQuery = Order::query();

        // Apply status filter to base query for KPI calculations
        if ($status !== 'all') {
            $baseQuery->byStatus($status);
        }

        // Total Orders (filtered by status)
        $totalOrders = (clone $baseQuery)->count();

        // Total Revenue (filtered by status, only paid orders)
        $totalRevenue = (clone $baseQuery)
            ->where('payment_status', Order::PAYMENT_PAID)
            ->sum('total_payable');

        // Average Order Value
        $avgOrderValue = $totalOrders > 0 ? ($totalRevenue / $totalOrders) : 0;

        // Today's Orders (filtered by status)
        $todayOrders = (clone $baseQuery)
            ->whereDate('created_at', $today)
            ->count();

        // Today's Revenue (filtered by status, only paid orders)
        $todayRevenue = (clone $baseQuery)
            ->whereDate('created_at', $today)
            ->where('payment_status', Order::PAYMENT_PAID)
            ->sum('total_payable');

        // Pending Orders (placed + processing)
        $pendingOrders = Order::whereIn('status', [
            Order::STATUS_PLACED,
            Order::STATUS_CONFIRMED,
            Order::STATUS_PACKED
        ])->count();

        // Fulfilled Orders (shipped + delivered)
        $fulfilledOrders = Order::whereIn('status', [Order::STATUS_SHIPPED, Order::STATUS_DELIVERED])
            ->count();

        // Unfulfilled Orders (placed + confirmed + packed)
        $unfulfilledOrders = Order::whereIn('status', [
            Order::STATUS_PLACED,
            Order::STATUS_CONFIRMED,
            Order::STATUS_PACKED
        ])->count();

        return [
            'total_orders' => $totalOrders,
            'total_revenue' => number_format($totalRevenue, 2, '.', ''),
            'avg_order_value' => number_format($avgOrderValue, 2, '.', ''),
            'today_orders' => $todayOrders,
            'today_revenue' => number_format($todayRevenue, 2, '.', ''),
            'pending_orders' => $pendingOrders,
            'fulfilled_orders' => $fulfilledOrders,
            'unfulfilled_orders' => $unfulfilledOrders,
        ];
    }

    /**
     * Generate order labels for a given date range and status.
     */
    public function orderMakingLabels(Request $request)
    {
        $date_from = $request->date_from;
        $date_to   = $request->date_to;
        $status      = $request->status ?? 'placed';
        $sort_search = $request->search ?? null;
	
	    $baseQuery = Order::query()->whereIn('status', ['placed','confirmed','packed','awaiting_pickup']);
	
        if (!empty($date_from)) {
            $date_to = $date_to ?? now()->format('Y-m-d');
            $baseQuery->whereBetween('created_at', [
                date('Y-m-d 00:00:00', strtotime($date_from)),
                date('Y-m-d 23:59:59', strtotime($date_to))
            ]);
        }else {
            $date_to = null;
        }

        if (!empty($sort_search)) {
            $baseQuery->where('id', $sort_search);
        }

        $orderStatusCounts = (clone $baseQuery)
            ->selectRaw('status, COUNT(*) as total')
            ->groupBy('status')
            ->pluck('total', 'status')
            ->toArray();

        $orderStatusCounts['all'] = (clone $baseQuery)->count();

        if (!empty($request->status)) {
            $baseQuery->where('status', $request->status);
            $status = $request->status;
        }

        $orders = $baseQuery->with(['items.product'])->orderByDesc('id')->get();

        if (Route::currentRouteName() === 'admin.making.orders.pdf') {
            $pdf = PDF::loadView('admin.orders.making_labels_pdf', 
                                compact('orders', 'date_from', 'date_to', 'status'), 
                                [], [
                                    'format'      => 'A4',
                                    'orientation' => 'P',
                                ]);

            $fileDate = $date_from ?? now()->format('Y-m-d') . ($date_to ? "_to_{$date_to}" : '');

            // Auto update placed -> confirmed
            if ($status === 'placed') {
                $placedIds = $orders->pluck('id');

                if ($placedIds->isNotEmpty()) {
                    Order::whereIn('id', $placedIds)->update([
                        'status' => 'confirmed'
                    ]);
                }
            }
            $pdf->download("order-labels-{$fileDate}.pdf");
        }
        
        return view('admin.orders.making_labels', compact('orders','status','date_from', 'date_to','orderStatusCounts','sort_search'));
    }
}
