<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Machine\Machine;
use App\Models\Machine\MachineSlot;
use App\Models\Machine\MachineStockMovement;
use App\Models\Product\Product;
use App\Models\Warehouse\ReplenishmentOrder;
use App\Models\Warehouse\ReplenishmentOrderItem;
use App\Models\Warehouse\StockInOrder;
use App\Models\Warehouse\StockInOrderItem;
use App\Models\Warehouse\StockMovement;
use App\Models\Warehouse\TransferOrder;
use App\Models\Warehouse\TransferOrderItem;
use App\Models\Warehouse\Warehouse;
use App\Models\Warehouse\WarehouseStock;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class WarehouseController extends Controller
{
    // ─── 模組 1：倉庫總覽 ───

    public function index(Request $request)
    {
        $query = Warehouse::query()
            ->with(['company'])
            ->withCount('stocks as products_count')
            ->withSum('stocks as total_stock', 'quantity');

        if ($search = $request->input('search')) {
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                    ->orWhere('address', 'like', "%{$search}%");
            });
        }

        if ($request->filled('type')) {
            $query->where('type', $request->input('type'));
        }

        $warehouses = $query->orderBy('type')->orderBy('name')
            ->paginate($request->input('per_page', 10))
            ->withQueryString();

        $stats = [
            'total' => Warehouse::count(),
            'main' => Warehouse::main()->count(),
            'branch' => Warehouse::branch()->count(),
            'low_stock' => WarehouseStock::lowStock()
                ->whereHas('warehouse', fn($q) => $q)->count(),
        ];

        $companies = collect();
        if (Auth::user()->isSystemAdmin()) {
            $companies = \App\Models\System\Company::active()->orderBy('name')->get();
        }

        return view('admin.warehouses.index', compact('warehouses', 'stats', 'companies'));
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'company_id' => Auth::user()->isSystemAdmin() ? 'nullable|exists:companies,id' : 'nullable',
            'name' => 'required|string|max:255',
            'type' => 'required|in:main,branch',
            'address' => 'nullable|string|max:500',
        ], [], [
            'name' => __('Warehouse Name'),
            'type' => __('Warehouse Type'),
            'company_id' => __('Company Name'),
        ]);

        if (!Auth::user()->isSystemAdmin()) {
            $validated['company_id'] = Auth::user()->company_id;
        }

        Warehouse::create($validated);

        if ($request->ajax() || $request->wantsJson()) {
            return response()->json([
                'success' => true,
                'message' => __('Warehouse created successfully'),
            ]);
        }

        return redirect()->route('admin.warehouses.index')
            ->with('success', __('Warehouse created successfully'));
    }

    public function update(Request $request, Warehouse $warehouse)
    {
        $rules = [
            'name' => 'required|string|max:255',
            'type' => 'required|in:main,branch',
            'address' => 'nullable|string|max:500',
            'is_active' => 'required|boolean',
        ];

        if (Auth::user()->isSystemAdmin()) {
            $rules['company_id'] = 'nullable|exists:companies,id';
        }

        $validated = $request->validate($rules, [], [
            'name' => __('Warehouse Name'),
            'type' => __('Warehouse Type'),
            'company_id' => __('Company Name'),
        ]);
        $warehouse->update($validated);

        if ($request->ajax() || $request->wantsJson()) {
            return response()->json([
                'success' => true,
                'message' => __('Warehouse updated successfully'),
            ]);
        }

        return redirect()->route('admin.warehouses.index')
            ->with('success', __('Warehouse updated successfully'));
    }

    public function destroy(Warehouse $warehouse)
    {
        if ($warehouse->stocks()->where('quantity', '>', 0)->exists()) {
            return redirect()->route('admin.warehouses.index')
                ->with('error', __('Cannot delete warehouse with existing stock'));
        }
        $warehouse->delete();

        return redirect()->route('admin.warehouses.index')
            ->with('success', __('Warehouse deleted successfully'));
    }

    public function toggleStatus(Warehouse $warehouse)
    {
        $warehouse->update(['is_active' => !$warehouse->is_active]);
        $status = $warehouse->is_active ? __('enabled') : __('disabled');

        return redirect()->route('admin.warehouses.index')
            ->with('success', __('Warehouse :status successfully', ['status' => $status]));
    }

    // ─── 模組 2：庫存管理 ───

    public function inventory(Request $request)
    {
        $tab = $request->input('tab', 'stock');
        $warehouses = Warehouse::active()->orderBy('name')->get();
        $isAjax = $request->ajax();

        $data = compact('warehouses', 'tab');

        // 1. Current Stocks (stock)
        if (!$isAjax || $tab === 'stock') {
            $warehouse_ids = $request->input('warehouse_ids');
            $inventory_warehouses = Warehouse::active()
                ->when($warehouse_ids, fn($q) => $q->whereIn('id', (array)$warehouse_ids))
                ->orderBy('name')
                ->get(['id', 'name', 'type']);
            
            $query = Product::with(['stocks' => function($q) {
                $q->select('id', 'product_id', 'warehouse_id', 'quantity', 'safety_stock');
            }, 'translations']);

            if ($warehouse_ids) {
                $query->whereHas('stocks', fn($q) => $q->whereIn('warehouse_id', (array)$warehouse_ids));
            }
            if ($search = $request->input('search')) {
                $query->where('name', 'like', "%{$search}%");
            }

            $data['inventory_warehouses'] = $inventory_warehouses;
            $data['products'] = $query->orderBy('name')
                ->paginate($request->input('per_page', 15), ['*'], 'stock_page')
                ->withQueryString();
        }

        // 2. Stock-In Orders (stock-in)
        if (!$isAjax || $tab === 'stock-in') {
            $query = StockInOrder::with(['warehouse:id,name', 'creator:id,name'])
                ->withCount('items')
                ->latest();

            if ($request->filled('status')) {
                $query->where('status', $request->input('status'));
            }
            if ($search = $request->input('search_order')) {
                $query->where('order_no', 'like', "%{$search}%");
            }
            if ($request->filled('start_date') || $request->filled('end_date')) {
                if ($request->filled('start_date')) {
                    $query->where('created_at', '>=', \Illuminate\Support\Carbon::parse($request->start_date));
                }
                if ($request->filled('end_date')) {
                    $query->where('created_at', '<=', \Illuminate\Support\Carbon::parse($request->end_date)->endOfMinute());
                }
            } else {
                // 隱性限制：預設只抓 6 個月內的單據以保護效能，但 UI 保持空白
                $query->where('created_at', '>=', now()->subMonths(6)->startOfDay());
                
                $data['stockInDefaultStart'] = '';
                $data['stockInDefaultEnd'] = '';
            }
            $data['orders'] = $query->paginate($request->input('per_page', 10), ['*'], 'order_page')->withQueryString();
            $data['stock_in_products'] = Product::with('translations')->orderBy('name')->get(['id', 'name', 'image_url', 'name_dictionary_key']);
        }

        // 3. Movement History (movements)
        if (!$isAjax || $tab === 'movements') {
            $query = StockMovement::with(['warehouse:id,name', 'product.translations', 'creator:id,name'])
                ->orderBy('created_at', 'desc')
                ->orderBy('id', 'desc');

            if ($request->filled('warehouse_id')) {
                $query->where('warehouse_id', $request->input('warehouse_id'));
            }
            if ($request->filled('type')) {
                $query->where('type', $request->input('type'));
            }
            if ($request->filled('start_date') || $request->filled('end_date')) {
                if ($request->filled('start_date')) {
                    $query->where('created_at', '>=', \Illuminate\Support\Carbon::parse($request->start_date));
                }
                if ($request->filled('end_date')) {
                    $query->where('created_at', '<=', \Illuminate\Support\Carbon::parse($request->end_date)->endOfMinute());
                }
            } else {
                // 預設當天
                $start = now()->startOfDay();
                $end = now()->endOfDay();
                $query->whereBetween('created_at', [$start, $end]);

                $data['movementDefaultStart'] = $start->format('Y-m-d H:i');
                $data['movementDefaultEnd'] = $end->format('Y-m-d H:i');

                // 只有在當前分頁是 movements 時才合併到 request
                if ($tab === 'movements') {
                    $request->merge([
                        'start_date' => $data['movementDefaultStart'],
                        'end_date' => $data['movementDefaultEnd']
                    ]);
                }
            }
            $data['movements'] = $query->paginate($request->input('per_page', 15), ['*'], 'movement_page')->withQueryString();
        }

        if ($isAjax) {
            return response()->json([
                'success' => true,
                'tab' => $tab,
                'html' => view('admin.warehouses.partials.tab-' . $tab, $data)->render()
            ]);
        }

        return view('admin.warehouses.inventory', $data);
    }

    /**
     * 建立入庫單
     */
    public function storeStockIn(Request $request)
    {
        $validated = $request->validate([
            'warehouse_id' => 'required|exists:warehouses,id',
            'note' => 'nullable|string|max:500',
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required|exists:products,id',
            'items.*.quantity' => 'required|integer|min:1',
        ], [
            'warehouse_id.required' => __('Please select target warehouse'),
            'items.required' => __('Please add at least one item'),
            'items.*.product_id.required' => __('Please select product for item :num', ['num' => ':position']),
            'items.*.quantity.min' => __('Please enter valid quantity for item :num', ['num' => ':position']),
        ]);

        DB::transaction(function () use ($validated) {
            $prefix = 'SI-' . now()->format('Ymd') . '-';
            $lastOrder = StockInOrder::withoutGlobalScopes()
                ->withTrashed()
                ->where('order_no', 'like', $prefix . '%')
                ->orderBy('order_no', 'desc')
                ->first();

            $nextNumber = $lastOrder ? (int)substr($lastOrder->order_no, -4) + 1 : 1;
            $order_no = $prefix . str_pad($nextNumber, 4, '0', STR_PAD_LEFT);

            $order = StockInOrder::create([
                'company_id' => Auth::user()->company_id,
                'warehouse_id' => $validated['warehouse_id'],
                'order_no' => $order_no,
                'status' => 'draft',
                'note' => $validated['note'] ?? null,
                'created_by' => Auth::id(),
            ]);

            foreach ($validated['items'] as $item) {
                $order->items()->create($item);
            }
        });

        if ($request->ajax()) {
            session()->flash('success', __('Stock-in order created successfully'));
            return response()->json([
                'success' => true,
                'message' => __('Stock-in order created successfully')
            ]);
        }

        return redirect()->route('admin.warehouses.inventory', ['tab' => 'stock-in'])
            ->with('success', __('Stock-in order created successfully'));
    }

    /**
     * 確認入庫單（草稿 → 完成，同時增加庫存）
     */
    public function confirmStockIn(StockInOrder $stockInOrder)
    {
        if ($stockInOrder->status !== StockInOrder::STATUS_DRAFT) {
            if (request()->ajax()) {
                return response()->json(['success' => false, 'message' => __('Order already processed')], 422);
            }
            return back()->with('error', __('Order already processed'));
        }

        DB::transaction(function () use ($stockInOrder) {
            $stockInOrder->update([
                'status' => StockInOrder::STATUS_COMPLETED,
                'completed_at' => now(),
            ]);

            foreach ($stockInOrder->items as $item) {
                // 更新或建立倉庫庫存
                $stock = WarehouseStock::firstOrCreate(
                    ['warehouse_id' => $stockInOrder->warehouse_id, 'product_id' => $item->product_id],
                    ['quantity' => 0, 'safety_stock' => 0]
                );

                $before = $stock->quantity;
                $stock->increment('quantity', $item->quantity);

                // 記錄異動
                StockMovement::create([
                    'company_id' => $stockInOrder->company_id,
                    'warehouse_id' => $stockInOrder->warehouse_id,
                    'product_id' => $item->product_id,
                    'type' => 'in',
                    'quantity' => $item->quantity,
                    'before_qty' => $before,
                    'after_qty' => $before + $item->quantity,
                    'reference_type' => StockInOrder::class,
                    'reference_id' => $stockInOrder->id,
                    'note' => __('Stock-in order') . ' #' . $stockInOrder->order_no,
                    'created_by' => Auth::id(),
                ]);
            }
        });

        if (request()->ajax()) {
            return response()->json([
                'success' => true,
                'message' => __('Stock-in order confirmed and inventory updated')
            ]);
        }

        return back()->with('success', __('Stock-in order confirmed and inventory updated'));
    }

    /**
     * 刪除入庫單（僅限草稿）
     */
    public function destroyStockIn(StockInOrder $stockInOrder)
    {
        if ($stockInOrder->status !== StockInOrder::STATUS_DRAFT) {
            if (request()->ajax()) {
                return response()->json(['success' => false, 'message' => __('Only draft orders can be deleted')], 422);
            }
            return back()->with('error', __('Only draft orders can be deleted'));
        }

        $stockInOrder->delete(); // Soft delete

        if (request()->ajax()) {
            return response()->json([
                'success' => true,
                'message' => __('Stock-in order deleted successfully')
            ]);
        }

        return back()->with('success', __('Stock-in order deleted successfully'));
    }

    // ─── 模組 3：調撥單 ───

    public function transfers(Request $request)
    {
        $query = TransferOrder::with(['fromWarehouse:id,name', 'toWarehouse:id,name', 'fromMachine:id,name,serial_no', 'creator:id,name'])
            ->withCount('items')
            ->latest();

        if ($request->filled('type')) {
            $query->where('type', $request->input('type'));
        }
        if ($request->filled('status')) {
            $query->where('status', $request->input('status'));
        }
        if ($search = $request->input('search_order')) {
            $query->where('order_no', 'like', "%{$search}%");
        }
        if ($request->filled('start_date') || $request->filled('end_date')) {
            if ($request->filled('start_date')) {
                $query->where('created_at', '>=', \Illuminate\Support\Carbon::parse($request->start_date));
            }
            if ($request->filled('end_date')) {
                $query->where('created_at', '<=', \Illuminate\Support\Carbon::parse($request->end_date)->endOfMinute());
            }
        } else {
            // 隱性限制：預設只抓 6 個月內的單據以保護效能，但 UI 保持空白
            $query->where('created_at', '>=', now()->subMonths(6)->startOfDay());
        }

        $orders = $query->paginate($request->input('per_page', 15))->withQueryString();

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'html' => view('admin.warehouses.partials.table-transfers', compact('orders'))->render()
            ]);
        }

        $warehouses = Warehouse::active()->orderBy('name')->get(['id', 'name']);
        $machines = Machine::orderBy('name')->get(['id', 'name', 'serial_no']);
        $products = Product::with('translations')->orderBy('name')->get(['id', 'name', 'image_url', 'name_dictionary_key']);
        
        $defaultStart = '';
        $defaultEnd = '';

        return view('admin.warehouses.transfers', compact('orders', 'warehouses', 'machines', 'products', 'defaultStart', 'defaultEnd'));
    }

    /**
     * 建立調撥單（W2W 或 M2W）
     */
    public function storeTransfer(Request $request)
    {
        $validated = $request->validate([
            'type' => 'required|in:warehouse_to_warehouse,machine_to_warehouse',
            'from_warehouse_id' => 'required_if:type,warehouse_to_warehouse|nullable|exists:warehouses,id',
            'from_machine_id' => 'required_if:type,machine_to_warehouse|nullable|exists:machines,id',
            'to_warehouse_id' => 'required|exists:warehouses,id',
            'note' => 'nullable|string|max:500',
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required|exists:products,id',
            'items.*.quantity' => 'required|integer|min:1',
        ], [
            'to_warehouse_id.required' => __('Please select target warehouse'),
            'from_warehouse_id.required_if' => __('Please select source warehouse'),
            'from_machine_id.required_if' => __('Please select source machine'),
            'items.required' => __('Please add at least one item'),
            'items.*.product_id.required' => __('Please select product for item :num', ['num' => ':position']),
            'items.*.quantity.min' => __('Please enter valid quantity for item :num', ['num' => ':position']),
        ]);

        DB::transaction(function () use ($validated) {
            $prefix = 'TR-' . now()->format('Ymd') . '-';
            $lastOrder = TransferOrder::withoutGlobalScopes()
                ->withTrashed()
                ->where('order_no', 'like', $prefix . '%')
                ->orderBy('order_no', 'desc')
                ->first();

            $nextNumber = $lastOrder ? (int)substr($lastOrder->order_no, -4) + 1 : 1;
            $order_no = $prefix . str_pad($nextNumber, 4, '0', STR_PAD_LEFT);

            $order = TransferOrder::create([
                'company_id' => Auth::user()->company_id,
                'order_no' => $order_no,
                'type' => $validated['type'],
                'from_warehouse_id' => $validated['from_warehouse_id'] ?? null,
                'from_machine_id' => $validated['from_machine_id'] ?? null,
                'to_warehouse_id' => $validated['to_warehouse_id'],
                'status' => TransferOrder::STATUS_DRAFT,
                'note' => $validated['note'] ?? null,
                'created_by' => Auth::id(),
            ]);

            // 預先取得商品資訊以建立快照
            $productIds = collect($validated['items'])->pluck('product_id')->unique()->toArray();
            $products = \App\Models\Product\Product::whereIn('id', $productIds)->get()->keyBy('id');

            foreach ($validated['items'] as $item) {
                $product = $products->get($item['product_id']);
                if ($product) {
                    $item['snapshot_product_name'] = $product->name;
                    $item['snapshot_product_name_key'] = $product->name_dictionary_key;
                    $item['snapshot_product_barcode'] = $product->barcode;
                    $item['snapshot_product_image_url'] = $product->image_url;
                }
                $order->items()->create($item);
            }
        });

        if ($request->ajax()) {
            session()->flash('success', __('Transfer order created successfully'));
            return response()->json([
                'success' => true,
                'message' => __('Transfer order created successfully')
            ]);
        }

        return redirect()->route('admin.warehouses.transfers')
            ->with('success', __('Transfer order created successfully'));
    }

    /**
     * 確認調撥（扣除來源庫存 + 增加目標庫存）
     */
    public function confirmTransfer(TransferOrder $transferOrder)
    {
        if ($transferOrder->status !== TransferOrder::STATUS_DRAFT) {
            if (request()->ajax()) {
                return response()->json(['success' => false, 'message' => __('Order already processed')], 422);
            }
            return back()->with('error', __('Order already processed'));
        }

        DB::transaction(function () use ($transferOrder) {
            $transferOrder->loadMissing('items');

            foreach ($transferOrder->items as $item) {
                // 扣除來源庫存（僅 W2W）
                if ($transferOrder->type === TransferOrder::TYPE_W2W && $transferOrder->from_warehouse_id) {
                    $fromStock = WarehouseStock::where('warehouse_id', $transferOrder->from_warehouse_id)
                        ->where('product_id', $item->product_id)->first();

                    if (!$fromStock || $fromStock->quantity < $item->quantity) {
                        throw new \Exception(__('Insufficient stock for transfer'));
                    }

                    $beforeFrom = $fromStock->quantity;
                    $fromStock->decrement('quantity', $item->quantity);

                    StockMovement::create([
                        'company_id' => $transferOrder->company_id,
                        'warehouse_id' => $transferOrder->from_warehouse_id,
                        'product_id' => $item->product_id,
                        'type' => 'transfer_out',
                        'quantity' => $item->quantity,
                        'before_qty' => $beforeFrom,
                        'after_qty' => $beforeFrom - $item->quantity,
                        'reference_type' => TransferOrder::class,
                        'reference_id' => $transferOrder->id,
                        'note' => __('Transfer out') . ' #' . $transferOrder->order_no,
                        'created_by' => Auth::id(),
                    ]);
                }

                // 增加目標倉庫庫存
                $toStock = WarehouseStock::firstOrCreate(
                    ['warehouse_id' => $transferOrder->to_warehouse_id, 'product_id' => $item->product_id],
                    ['quantity' => 0, 'safety_stock' => 0]
                );
                $beforeTo = $toStock->quantity;
                $toStock->increment('quantity', $item->quantity);

                StockMovement::create([
                    'company_id' => $transferOrder->company_id,
                    'warehouse_id' => $transferOrder->to_warehouse_id,
                    'product_id' => $item->product_id,
                    'type' => 'transfer_in',
                    'quantity' => $item->quantity,
                    'before_qty' => $beforeTo,
                    'after_qty' => $beforeTo + $item->quantity,
                    'reference_type' => TransferOrder::class,
                    'reference_id' => $transferOrder->id,
                    'note' => __('Transfer in') . ' #' . $transferOrder->order_no,
                    'created_by' => Auth::id(),
                ]);
            }

            $transferOrder->update([
                'status' => TransferOrder::STATUS_COMPLETED,
                'completed_at' => now(),
            ]);
        });

        if (request()->ajax()) {
            return response()->json([
                'success' => true,
                'message' => __('Transfer order confirmed and inventory updated')
            ]);
        }

        return back()->with('success', __('Transfer order confirmed and inventory updated'));
    }

    /**
     * 刪除調撥單（僅限草稿）
     */
    public function destroyTransfer(TransferOrder $transferOrder)
    {
        if ($transferOrder->status !== TransferOrder::STATUS_DRAFT) {
            if (request()->ajax()) {
                return response()->json(['success' => false, 'message' => __('Only draft orders can be deleted')], 422);
            }
            return back()->with('error', __('Only draft orders can be deleted'));
        }

        $transferOrder->delete(); // Soft delete

        if (request()->ajax()) {
            return response()->json([
                'success' => true,
                'message' => __('Transfer order deleted successfully')
            ]);
        }

        return back()->with('success', __('Transfer order deleted successfully'));
    }

    // ─── 模組 4：機台庫存總覽 ───

    public function machineInventory(Request $request)
    {
        $query = Machine::with(['slots' => fn($q) => $q->with('product:id,name,image_url')->orderByRaw('CAST(slot_no AS UNSIGNED) ASC')])
            ->withCount('slots as total_slots')
            ->withSum('slots as total_stock', 'stock')
            ->withSum('slots as total_capacity', 'max_stock');

        if ($search = $request->input('search')) {
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                    ->orWhere('serial_no', 'like', "%{$search}%");
            });
        }

        // 預設按庫存率由低到高排序 (補貨優先)，在庫存率相同時再按名稱排序
        $machines = $query->orderByRaw('CASE WHEN total_capacity > 0 THEN (total_stock / total_capacity) ELSE 1 END ASC')
            ->orderBy('name')
            ->paginate($request->input('per_page', 10))
            ->withQueryString();

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'html' => view('admin.warehouses.partials.list-machines', compact('machines'))->render()
            ]);
        }

        return view('admin.warehouses.machine-inventory', compact('machines'));
    }


    /**
     * AJAX：取得單台機台貨道詳情
     */
    public function machineSlots(Machine $machine)
    {
        $slots = $machine->slots()
            ->with(['product:id,name,image_url,barcode,price'])
            ->orderByRaw('CAST(slot_no AS UNSIGNED) ASC')
            ->get();

        // 取得流水帳中出現過的所有貨道編號 (包含已移除的)
        $historicalSlotNos = MachineStockMovement::where('machine_id', $machine->id)
            ->distinct()
            ->pluck('slot_no')
            ->map(fn($val) => (string)$val)
            ->toArray();

        return response()->json([
            'success' => true, 
            'machine' => $machine,
            'slots' => $slots,
            'historical_slot_nos' => $historicalSlotNos
        ]);
    }

    /**
     * 機台庫存異動紀錄 (AJAX) — 供 Slide-out Panel 使用
     */
    public function machineStockMovements(Request $request, Machine $machine)
    {
        $query = $machine->stockMovements()
            ->with(['product:id,name', 'creator:id,name'])
            ->latest();

        if ($request->filled('type')) {
            $query->where('type', $request->input('type'));
        }
        if ($request->filled('slot_no')) {
            $query->where('slot_no', $request->input('slot_no'));
        }
        if ($request->filled('date_from')) {
            $query->whereDate('created_at', '>=', $request->input('date_from'));
        }
        if ($request->filled('date_to')) {
            $query->whereDate('created_at', '<=', $request->input('date_to'));
        }

        $movements = $query->paginate($request->input('per_page', 20))->withQueryString();

        return response()->json([
            'success'   => true,
            'movements' => $movements->items(),
            'meta'      => [
                'current_page' => $movements->currentPage(),
                'last_page'    => $movements->lastPage(),
                'total'        => $movements->total(),
            ],
        ]);
    }

    // ─── 模組 5：機台補貨 ───

    public function replenishments(Request $request)
    {
        $query = ReplenishmentOrder::with(['warehouse:id,name', 'machine:id,name,serial_no', 'assignee:id,name', 'creator:id,name'])
            ->withCount('items')
            ->latest();

        if ($request->filled('status')) {
            $query->where('status', $request->input('status'));
        }
        if ($search = $request->input('search_order')) {
            $query->where('order_no', 'like', "%{$search}%");
        }
        if ($request->filled('start_date') || $request->filled('end_date')) {
            if ($request->filled('start_date')) {
                $query->where('created_at', '>=', \Illuminate\Support\Carbon::parse($request->start_date));
            }
            if ($request->filled('end_date')) {
                $query->where('created_at', '<=', \Illuminate\Support\Carbon::parse($request->end_date)->endOfMinute());
            }
        } else {
            // 隱性限制：預設只抓 6 個月內的單據以保護效能，但 UI 保持空白
            $query->where('created_at', '>=', now()->subMonths(6)->startOfDay());
        }

        $orders = $query->paginate($request->input('per_page', 10))->withQueryString();

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'html' => view('admin.warehouses.partials.table-replenishments', compact('orders'))->render()
            ]);
        }

        $warehouses = Warehouse::active()->orderBy('name')->get(['id', 'name']);
        $machines = Machine::orderBy('name')->get(['id', 'name', 'serial_no']);
        $products = Product::with('translations')->orderBy('name')->get(['id', 'name', 'image_url', 'name_dictionary_key']);

        $userQuery = \App\Models\System\User::where('status', 1)->orderBy('name');
        if (!Auth::user()->isSystemAdmin()) {
            $userQuery->where('company_id', Auth::user()->company_id);
        }
        $users = $userQuery->get(['id', 'name']);

        $defaultStart = '';
        $defaultEnd = '';

        return view('admin.warehouses.replenishments', compact('orders', 'warehouses', 'machines', 'products', 'users', 'defaultStart', 'defaultEnd'));
    }

    /**
     * 建立補貨單（含 current_stock/max_stock 快照）
     */
    public function storeReplenishment(Request $request)
    {
        $validated = $request->validate([
            'warehouse_id' => 'required|exists:warehouses,id',
            'machine_id' => 'required|exists:machines,id',
            'note' => 'nullable|string|max:500',
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required|exists:products,id',
            'items.*.slot_no' => 'required|integer',
            'items.*.quantity' => 'required|integer|min:1',
            'items.*.current_stock' => 'nullable|integer|min:0',
            'items.*.max_stock' => 'nullable|integer|min:0',
        ], [
            'warehouse_id.required' => __('Please select source warehouse'),
            'machine_id.required' => __('Please select target machine'),
            'items.required' => __('Please add at least one item'),
            'items.*.product_id.required' => __('Please select product for item :num', ['num' => ':position']),
            'items.*.quantity.min' => __('Please enter valid quantity for item :num', ['num' => ':position']),
        ]);

        DB::transaction(function () use ($validated) {
            $prefix = 'RP-' . now()->format('Ymd') . '-';
            $lastOrder = ReplenishmentOrder::withoutGlobalScopes()
                ->withTrashed()
                ->where('order_no', 'like', $prefix . '%')
                ->orderBy('order_no', 'desc')
                ->first();

            $nextNumber = $lastOrder ? (int)substr($lastOrder->order_no, -4) + 1 : 1;
            $order_no = $prefix . str_pad($nextNumber, 4, '0', STR_PAD_LEFT);

            $order = ReplenishmentOrder::create([
                'company_id' => Auth::user()->company_id,
                'order_no' => $order_no,
                'warehouse_id' => $validated['warehouse_id'],
                'machine_id' => $validated['machine_id'],
                'status' => ReplenishmentOrder::STATUS_PENDING,
                'note' => $validated['note'] ?? null,
                'created_by' => Auth::id(),
            ]);

            // 預先取得商品資訊以建立快照
            $productIds = collect($validated['items'])->pluck('product_id')->unique()->toArray();
            $products = \App\Models\Product\Product::whereIn('id', $productIds)->get()->keyBy('id');

            // 批量寫入明細（遵循 DB Best Practice: 不在迴圈中逐筆 create）
            $itemsData = [];
            foreach ($validated['items'] as $item) {
                $product = $products->get($item['product_id']);
                $itemsData[] = [
                    'replenishment_order_id' => $order->id,
                    'product_id' => $item['product_id'],
                    'slot_no' => $item['slot_no'],
                    'quantity' => $item['quantity'],
                    'current_stock' => $item['current_stock'] ?? 0,
                    'max_stock' => $item['max_stock'] ?? 0,
                    'snapshot_product_name' => $product ? $product->name : null,
                    'snapshot_product_name_key' => $product ? $product->name_dictionary_key : null,
                    'snapshot_product_barcode' => $product ? $product->barcode : null,
                    'snapshot_product_image_url' => $product ? $product->image_url : null,
                    'created_at' => now(),
                    'updated_at' => now(),
                ];
            }
            ReplenishmentOrderItem::insert($itemsData);
        });

        session()->flash('success', __('Replenishment order created successfully'));

        return redirect()->route('admin.warehouses.replenishments');
    }

    /**
     * 自動補貨單 — 自動讀取機台所有貨道，計算 max_stock - stock
     */
    public function autoReplenishment(Request $request)
    {
        $validated = $request->validate([
            'warehouse_id' => 'required|exists:warehouses,id',
            'machine_id' => 'required|exists:machines,id',
            'note' => 'nullable|string|max:500',
            'items' => 'nullable|array',
            'items.*.slot_no' => 'required_with:items|integer',
            'items.*.product_id' => 'required_with:items|exists:products,id',
            'items.*.quantity' => 'required_with:items|integer|min:1',
            'items.*.current_stock' => 'nullable|integer|min:0',
            'items.*.max_stock' => 'nullable|integer|min:0',
        ]);

        $machine = Machine::findOrFail($validated['machine_id']);

        // 如果前端未提供 items（首次請求），自動計算補貨清單
        if (empty($validated['items'])) {
            $slots = MachineSlot::with('product:id,name,image_url,name_dictionary_key')
                ->where('machine_id', $machine->id)
                ->whereNotNull('product_id')
                ->whereColumn('stock', '<', 'max_stock')
                ->orderByRaw('CAST(slot_no AS UNSIGNED) ASC')
                ->get();

            if ($slots->isEmpty()) {
                return response()->json([
                    'success' => false,
                    'message' => __('All slots are fully stocked')
                ], 422);
            }

            // 檢查倉庫庫存
            $warehouse = Warehouse::findOrFail($validated['warehouse_id']);
            $warehouseStocks = WarehouseStock::where('warehouse_id', $warehouse->id)
                ->pluck('quantity', 'product_id');

            // 按商品彙總需求量
            $demandByProduct = [];
            foreach ($slots as $slot) {
                $pid = $slot->product_id;
                $need = $slot->max_stock - $slot->stock;
                $demandByProduct[$pid] = ($demandByProduct[$pid] ?? 0) + $need;
            }

            // 檢查是否有庫存不足的商品
            $insufficientProducts = [];
            foreach ($demandByProduct as $pid => $totalNeed) {
                $available = $warehouseStocks[$pid] ?? 0;
                if ($available < $totalNeed) {
                    $insufficientProducts[$pid] = [
                        'available' => $available,
                        'needed' => $totalNeed,
                    ];
                }
            }

            $slotData = $slots->map(fn($s) => [
                'slot_no' => $s->slot_no,
                'product_id' => $s->product_id,
                'product_name' => $s->product?->localized_name ?? 'Unknown',
                'image_url' => $s->product?->image_url,
                'current_stock' => $s->stock,
                'max_stock' => $s->max_stock,
                'quantity' => $s->max_stock - $s->stock,
            ]);

            return response()->json([
                'success' => true,
                'preview' => true,
                'machine_name' => $machine->name,
                'slots' => $slotData,
                'insufficient' => $insufficientProducts,
                'warehouse_stocks' => $warehouseStocks,
                'has_warning' => !empty($insufficientProducts),
            ]);
        }

        // 有 items = 確認建單
        DB::transaction(function () use ($validated) {
            $prefix = 'RP-' . now()->format('Ymd') . '-';
            $lastOrder = ReplenishmentOrder::withoutGlobalScopes()
                ->withTrashed()
                ->where('order_no', 'like', $prefix . '%')
                ->orderBy('order_no', 'desc')
                ->first();

            $nextNumber = $lastOrder ? (int)substr($lastOrder->order_no, -4) + 1 : 1;
            $order_no = $prefix . str_pad($nextNumber, 4, '0', STR_PAD_LEFT);

            $order = ReplenishmentOrder::create([
                'company_id' => Auth::user()->company_id,
                'order_no' => $order_no,
                'warehouse_id' => $validated['warehouse_id'],
                'machine_id' => $validated['machine_id'],
                'status' => ReplenishmentOrder::STATUS_PENDING,
                'note' => $validated['note'] ?? __('Auto Replenishment'),
                'created_by' => Auth::id(),
            ]);

            // 預先取得商品資訊以建立快照
            $productIds = collect($validated['items'])->pluck('product_id')->unique()->toArray();
            $products = \App\Models\Product\Product::whereIn('id', $productIds)->get()->keyBy('id');

            $itemsData = [];
            foreach ($validated['items'] as $item) {
                $product = $products->get($item['product_id']);
                $itemsData[] = [
                    'replenishment_order_id' => $order->id,
                    'product_id' => $item['product_id'],
                    'slot_no' => $item['slot_no'],
                    'quantity' => $item['quantity'],
                    'current_stock' => $item['current_stock'] ?? 0,
                    'max_stock' => $item['max_stock'] ?? 0,
                    'snapshot_product_name' => $product ? $product->name : null,
                    'snapshot_product_name_key' => $product ? $product->name_dictionary_key : null,
                    'snapshot_product_barcode' => $product ? $product->barcode : null,
                    'snapshot_product_image_url' => $product ? $product->image_url : null,
                    'created_at' => now(),
                    'updated_at' => now(),
                ];
            }
            ReplenishmentOrderItem::insert($itemsData);
        });

        session()->flash('success', __('Replenishment order created successfully'));
        return response()->json([
            'success' => true,
            'message' => __('Replenishment order created successfully')
        ]);
    }

    /**
     * 狀態推進 (pending → prepared → delivering → completed)
     */
    public function updateReplenishmentStatus(Request $request, ReplenishmentOrder $replenishmentOrder)
    {
        $validated = $request->validate([
            'status' => 'required|in:prepared,delivering,completed',
            'assigned_to' => 'nullable|exists:users,id',
        ]);

        $newStatus = $validated['status'];

        if (!$replenishmentOrder->canTransitionTo($newStatus)) {
            return response()->json([
                'success' => false,
                'message' => __('Invalid status transition')
            ], 422);
        }

        DB::transaction(function () use ($replenishmentOrder, $newStatus, $validated) {
            $replenishmentOrder->loadMissing('items');

            // 更新指派人員 (如果有傳遞的話)
            if (array_key_exists('assigned_to', $validated)) {
                $replenishmentOrder->assigned_to = $validated['assigned_to'];
            }

            // pending → prepared：扣減倉庫庫存
            if ($newStatus === ReplenishmentOrder::STATUS_PREPARED) {
                foreach ($replenishmentOrder->items as $item) {
                    $stock = WarehouseStock::firstOrCreate(
                        [
                            'warehouse_id' => $replenishmentOrder->warehouse_id,
                            'product_id' => $item->product_id,
                        ],
                        [
                            'company_id' => $replenishmentOrder->company_id,
                            'quantity' => 0,
                        ]
                    );

                    $stock->lockForUpdate();

                    $before = $stock->quantity;
                    $stock->decrement('quantity', $item->quantity);

                    StockMovement::create([
                        'company_id' => $replenishmentOrder->company_id,
                        'warehouse_id' => $replenishmentOrder->warehouse_id,
                        'product_id' => $item->product_id,
                        'type' => 'out',
                        'quantity' => $item->quantity,
                        'before_qty' => $before,
                        'after_qty' => $before - $item->quantity,
                        'reference_type' => ReplenishmentOrder::class,
                        'reference_id' => $replenishmentOrder->id,
                        'note' => __('Replenishment prepare') . ' #' . $replenishmentOrder->order_no,
                        'created_by' => Auth::id(),
                    ]);
                }
            }

            // delivering → completed：增加機台貨道庫存並記錄異動
            if ($newStatus === ReplenishmentOrder::STATUS_COMPLETED) {
                foreach ($replenishmentOrder->items as $item) {
                    $slot = MachineSlot::where('machine_id', $replenishmentOrder->machine_id)
                        ->where('slot_no', $item->slot_no)
                        ->lockForUpdate()
                        ->first();

                    if ($slot) {
                        $beforeQty = $slot->stock;
                        $slot->increment('stock', $item->quantity);
                        $slot->refresh();

                        MachineStockMovement::create([
                            'company_id'     => $replenishmentOrder->company_id,
                            'machine_id'     => $replenishmentOrder->machine_id,
                            'product_id'     => $item->product_id,
                            'slot_no'        => $item->slot_no,
                            'type'           => MachineStockMovement::TYPE_REPLENISHMENT,
                            'quantity'       => $item->quantity,
                            'before_qty'     => $beforeQty,
                            'after_qty'      => $slot->stock,
                            'reference_type' => ReplenishmentOrder::class,
                            'reference_id'   => $replenishmentOrder->id,
                            'note'           => '補貨單完成入庫 #' . $replenishmentOrder->order_no,
                            'created_by'     => Auth::id(),
                        ]);
                    }
                }

                $replenishmentOrder->completed_at = now();
            }

            $replenishmentOrder->status = $newStatus;
            $replenishmentOrder->save();
        });

        $statusLabels = [
            'prepared' => __('Confirm Prepare'),
            'delivering' => __('Start Delivery'),
            'completed' => __('Confirm Complete'),
        ];

        $statusMessages = [
            'prepared' => __('Order prepared successfully, stock deducted'),
            'delivering' => __('Order is now in delivery'),
            'completed' => __('Order completed and stock updated'),
        ];

        session()->flash('success', $statusMessages[$newStatus] ?? __('Status updated successfully'));

        return response()->json([
            'success' => true,
            'message' => __('Status updated successfully')
        ]);
    }

    /**
     * 取消補貨單 — 若已備貨/配送中則退回倉庫庫存
     */
    public function cancelReplenishment(ReplenishmentOrder $replenishmentOrder)
    {
        if (!$replenishmentOrder->canTransitionTo(ReplenishmentOrder::STATUS_CANCELLED)) {
            return response()->json([
                'success' => false,
                'message' => __('Cannot cancel this order')
            ], 422);
        }

        DB::transaction(function () use ($replenishmentOrder) {
            // 若已備貨(prepared)或配送中(delivering)，需退回倉庫庫存
            if (in_array($replenishmentOrder->status, [ReplenishmentOrder::STATUS_PREPARED, ReplenishmentOrder::STATUS_DELIVERING])) {
                $replenishmentOrder->loadMissing('items');

                foreach ($replenishmentOrder->items as $item) {
                    $stock = WarehouseStock::firstOrCreate(
                        [
                            'warehouse_id' => $replenishmentOrder->warehouse_id,
                            'product_id' => $item->product_id,
                        ],
                        [
                            'company_id' => $replenishmentOrder->company_id,
                            'quantity' => 0,
                        ]
                    );

                    $stock->lockForUpdate();

                    $before = $stock->quantity;
                    $stock->increment('quantity', $item->quantity);

                    StockMovement::create([
                        'company_id' => $replenishmentOrder->company_id,
                        'warehouse_id' => $replenishmentOrder->warehouse_id,
                        'product_id' => $item->product_id,
                        'type' => 'in',
                        'quantity' => $item->quantity,
                        'before_qty' => $before,
                        'after_qty' => $before + $item->quantity,
                        'reference_type' => ReplenishmentOrder::class,
                        'reference_id' => $replenishmentOrder->id,
                        'note' => __('Replenishment cancelled, stock returned') . ' #' . $replenishmentOrder->order_no,
                        'created_by' => Auth::id(),
                    ]);
                }
            }

            $replenishmentOrder->update([
                'status' => ReplenishmentOrder::STATUS_CANCELLED,
            ]);
        });

        $msg = __('Order has been cancelled');
        if (in_array($replenishmentOrder->getOriginal('status'), [ReplenishmentOrder::STATUS_PREPARED, ReplenishmentOrder::STATUS_DELIVERING])) {
            $msg .= ' — ' . __('Stock returned to warehouse');
        }

        session()->flash('success', $msg);

        return response()->json([
            'success' => true,
            'message' => $msg
        ]);
    }

    /**
     * 指派補貨人員（僅限同租戶帳號）
     */
    public function assignReplenishment(Request $request, ReplenishmentOrder $replenishmentOrder)
    {
        $validated = $request->validate([
            'assigned_to' => 'nullable|exists:users,id',
        ]);

        if ($validated['assigned_to']) {
            // 確保指派人員屬於同租戶
            $user = \App\Models\System\User::where('id', $validated['assigned_to'])
                ->where('company_id', Auth::user()->company_id)
                ->first();

            if (!$user) {
                return response()->json([
                    'success' => false,
                    'message' => __('Invalid personnel selection')
                ], 422);
            }
            $replenishmentOrder->assigned_to = $user->id;
        } else {
            $replenishmentOrder->assigned_to = null;
        }

        session()->flash('success', __('Personnel assigned successfully'));

        return response()->json([
            'success' => true,
            'message' => __('Personnel assigned successfully')
        ]);
    }

    /**
     * AJAX：取得特定機台的貨道資訊供補貨選擇
     */
    public function getMachineSlotsForReplenishment(Machine $machine)
    {
        $slots = $machine->slots()
            ->with(['product' => fn($q) => $q->select('id', 'name', 'image_url', 'name_dictionary_key')->with('translations')])
            ->orderByRaw('CAST(slot_no AS UNSIGNED) ASC')
            ->get();

        return response()->json([
            'success' => true,
            'machine' => [
                'id' => $machine->id,
                'name' => $machine->name,
                'serial_no' => $machine->serial_no,
            ],
            'slots' => $slots->map(fn($s) => [
                'slot_no' => $s->slot_no,
                'product_id' => $s->product_id,
                'product_name' => $s->product?->localized_name ?? null,
                'image_url' => $s->product?->image_url,
                'stock' => $s->stock,
                'max_stock' => $s->max_stock,
                'needs_replenishment' => $s->product_id && $s->stock < $s->max_stock,
            ]),
        ]);
    }

    /**
     * AJAX：取得補貨單詳情
     */
    public function replenishmentOrderDetails(Request $request, $id)
    {
        $order = ReplenishmentOrder::with(['machine', 'warehouse', 'creator', 'assignee'])
            ->where('id', $id)
            ->firstOrFail();

        $items = ReplenishmentOrderItem::with(['translations', 'product.translations'])
            ->where('replenishment_order_id', $id)
            ->get()
            ->map(function ($item) {
                return [
                    'product_id' => $item->product_id,
                    'product_name' => $item->localized_name ?: __('Unknown'),
                    'image_url' => $item->image_url,
                    'quantity' => $item->quantity,
                    'slot_no' => $item->slot_no,
                    'current_stock' => $item->current_stock,
                    'max_stock' => $item->max_stock,
                ];
            });

        return response()->json([
            'success' => true,
            'order' => [
                'id' => $order->id,
                'order_no' => $order->order_no,
                'status' => $order->status,
                'machine_name' => $order->machine?->name,
                'machine_serial' => $order->machine?->serial_no,
                'warehouse_name' => $order->warehouse?->name,
                'creator_name' => $order->creator?->name,
                'assignee_name' => $order->assignee?->name,
                'note' => $order->note,
                'created_at' => $order->created_at->format('Y-m-d H:i:s'),
                'completed_at' => $order->completed_at?->format('Y-m-d H:i:s'),
            ],
            'items' => $items
        ]);
    }

    /**
     * 舊版 confirmReplenishment 已重構為 updateReplenishmentStatus
     * 保留向下相容
     */
    public function confirmReplenishment(ReplenishmentOrder $replenishmentOrder)
    {
        // 模擬直接完成流程：pending → completed
        request()->merge(['status' => 'completed']);
        return $this->updateReplenishmentStatus(request(), $replenishmentOrder);
    }

    /**
     * AJAX：取得來源庫存（倉庫或機台）
     */
    public function getStockAjax(Request $request)
    {
        $warehouseId = $request->input('warehouse_id');
        $machineId = $request->input('machine_id');

        try {
            if ($warehouseId) {
                // Warehouse uses TenantScoped, findOrFail will respect it
                $warehouse = Warehouse::findOrFail($warehouseId);
                
                // 獲取公司所有啟動中的商品
                $products = Product::where('company_id', $warehouse->company_id)
                    ->active()
                    ->select('id', 'name', 'image_url', 'name_dictionary_key')
                    ->with('translations')
                    ->get();
                
                // 獲取目前的庫存量（用於顯示，不限制選擇）
                $stocks = WarehouseStock::where('warehouse_id', $warehouse->id)
                    ->pluck('quantity', 'product_id');

                $data = $products->map(fn($p) => [
                    'id' => $p->id,
                    'name' => $p->localized_name ?? 'Unknown',
                    'quantity' => $stocks[$p->id] ?? 0,
                    'image' => $p->image_url
                ]);
            } elseif ($machineId) {
                // Machine uses TenantScoped and machine_access scope
                $machine = Machine::findOrFail($machineId);
                $slots = MachineSlot::with(['product' => fn($q) => $q->select('id', 'name', 'image_url', 'name_dictionary_key')->with('translations')])
                    ->where('machine_id', $machine->id)
                    ->where('stock', '>', 0)
                    ->get()
                    ->groupBy('product_id');

                $data = $slots->map(function($group) {
                    $p = $group->first()->product;
                    return [
                        'id' => $group->first()->product_id,
                        'name' => $p?->localized_name ?? 'Unknown',
                        'quantity' => $group->sum('stock'),
                        'image' => $p?->image_url
                    ];
                })->values();
            } else {
                return response()->json(['success' => false, 'message' => __('No source provided')]);
            }
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => __('Unauthorized or not found')]);
        }

        return response()->json(['success' => true, 'data' => $data]);
    }

    /**
     * AJAX：取得倉庫商品庫存詳情 (用於滑出面板)
     */
    public function warehouseStocks(Warehouse $warehouse, Request $request)
    {
        $query = $warehouse->stocks()->with(['product' => fn($q) => $q->select('id', 'name', 'image_url', 'name_dictionary_key')->with('translations')]);

        if ($search = $request->input('search')) {
            $query->whereHas('product', fn($q) => $q->where('name', 'like', "%{$search}%"));
        }

        $stocks = $query->get();

        return response()->json([
            'success' => true,
            'warehouse' => [
                'id' => $warehouse->id,
                'name' => $warehouse->name,
                'type' => $warehouse->type,
            ],
            'stocks' => $stocks->map(fn($s) => [
                'id' => $s->id,
                'product_id' => $s->product_id,
                'product_name' => $s->product?->localized_name ?? 'Unknown',
                'image_url' => $s->product?->image_url,
                'quantity' => (int)$s->quantity,
                'safety_stock' => (int)$s->safety_stock,
            ])
        ]);
    }

    /**
     * AJAX：取得進貨單詳情
     */
    public function stockInOrderDetails(StockInOrder $order)
    {
        $order->load(['warehouse', 'creator', 'items.product.translations']);

        return response()->json([
            'success' => true,
            'order' => [
                'id' => $order->id,
                'order_no' => $order->order_no,
                'status' => $order->status,
                'warehouse_name' => $order->warehouse?->name,
                'creator_name' => $order->creator?->name,
                'created_at' => $order->created_at?->format('Y-m-d H:i:s'),
                'completed_at' => $order->completed_at?->format('Y-m-d H:i:s'),
                'note' => $order->note,
            ],
            'items' => $order->items->map(fn($item) => [
                'product_name' => $item->product?->localized_name ?? 'Unknown',
                'image_url' => $item->product?->image_url,
                'quantity' => $item->quantity,
            ])
        ]);
    }


    /**
     * Get transfer order details for AJAX.
     */
    public function transferOrderDetails(Request $request, $id)
    {
        $order = TransferOrder::with(['fromWarehouse', 'toWarehouse', 'fromMachine', 'creator'])
            ->where('id', $id)
            ->firstOrFail();

        $items = \App\Models\Warehouse\TransferOrderItem::with(['translations', 'product.translations'])
            ->where('transfer_order_id', $id)
            ->get()
            ->map(function($item) {
                return [
                    'product_id' => $item->product_id,
                    'product_name' => $item->localized_name ?: __('Unknown'),
                    'image_url' => $item->image_url,
                    'quantity' => (int)$item->quantity,
                ];
            });

        return response()->json([
            'success' => true,
            'order' => [
                'id' => $order->id,
                'order_no' => $order->order_no,
                'type' => $order->type,
                'from_name' => $order->type === 'warehouse_to_warehouse' 
                    ? ($order->fromWarehouse?->name ?? __('Unknown'))
                    : ($order->fromMachine?->name ?? __('Unknown')),
                'to_name' => $order->toWarehouse?->name ?? __('Unknown'),
                'status' => $order->status,
                'creator_name' => $order->creator?->name ?? __('System'),
                'note' => $order->note,
                'created_at' => $order->created_at->format('Y-m-d H:i:s'),
                'completed_at' => $order->completed_at?->format('Y-m-d H:i:s'),
            ],
            'items' => $items
        ]);
    }

    /**
     * 列印調撥單
     */
    public function printTransfer($id)
    {
        $order = TransferOrder::with(['fromWarehouse', 'toWarehouse', 'fromMachine', 'creator'])
            ->findOrFail($id);

        // 雙重防護：驗證租戶資料隔離安全
        $user = auth()->user();
        if ($user && $user->company_id && $order->company_id !== $user->company_id) {
            abort(404);
        }

        $items = \App\Models\Warehouse\TransferOrderItem::with(['product' => fn($q) => $q->with('translations')])
            ->where('transfer_order_id', $id)
            ->get();

        return view('admin.warehouses.print.transfer', compact('order', 'items'));
    }

    /**
     * 列印機台補貨單
     */
    public function printReplenishment($id)
    {
        $order = ReplenishmentOrder::with(['machine', 'warehouse', 'creator', 'assignee'])
            ->findOrFail($id);

        // 雙重防護：驗證租戶資料隔離安全
        $user = auth()->user();
        if ($user && $user->company_id && $order->company_id !== $user->company_id) {
            abort(404);
        }

        $items = ReplenishmentOrderItem::with(['product' => fn($q) => $q->with('translations')])
            ->where('replenishment_order_id', $id)
            ->get();

        return view('admin.warehouses.print.replenishment', compact('order', 'items'));
    }
}

