<?php

namespace App\Modules\Inventory\Controllers;

use App\Http\Controllers\Controller;
use App\Enums\WarehouseType;
use App\Modules\Inventory\Models\InventoryTransferOrder;
use App\Modules\Inventory\Models\Warehouse;
use App\Modules\Inventory\Models\Inventory;
use App\Modules\Inventory\Services\TransferService;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Inertia\Inertia;

class TransferOrderController extends Controller
{
    protected $transferService;

    public function __construct(TransferService $transferService)
    {
        $this->transferService = $transferService;
    }

    public function index(Request $request)
    {
        $query = InventoryTransferOrder::query()
             ->with(['fromWarehouse', 'toWarehouse', 'createdBy', 'postedBy']);

        // 搜尋：單號或備註
        if ($request->filled('search')) {
            $query->where(function ($q) use ($request) {
                $q->where('doc_no', 'like', "%{$request->search}%")
                  ->orWhere('remarks', 'like', "%{$request->search}%");
            });
        }

        // 篩選：若有選定倉庫，則顯示該倉庫作為來源或目的地的調撥單
        if ($request->filled('warehouse_id')) {
             $query->where(function ($q) use ($request) {
                $q->where('from_warehouse_id', $request->warehouse_id)
                  ->orWhere('to_warehouse_id', $request->warehouse_id);
            });
        }

        $defaultPerPage = \App\Modules\Core\Models\SystemSetting::getVal('display.per_page', 10);
        $perPage = $request->input('per_page', $defaultPerPage);
        if (!in_array((int)$perPage, [10, 20, 50, 100])) {
            $perPage = $defaultPerPage;
        }
        $orders = $query->orderByDesc('created_at')
            ->paginate($perPage)
            ->withQueryString()
            ->through(function ($order) {
                return [
                    'id' => (string) $order->id,
                    'doc_no' => $order->doc_no,
                    'from_warehouse_name' => $order->fromWarehouse->name,
                    'to_warehouse_name' => $order->toWarehouse->name,
                    'status' => $order->status,
                    'created_at' => $order->created_at->format('Y-m-d H:i'),
                    'posted_at' => $order->posted_at ? $order->posted_at->format('Y-m-d H:i') : '-',
                    'created_by' => $order->createdBy?->name,
                ];
            });

        return Inertia::render('Inventory/Transfer/Index', [
            'orders' => $orders,
            'warehouses' => Warehouse::select('id', 'name')->get()->map(fn($w) => ['id' => (string)$w->id, 'name' => $w->name]),
            'filters' => $request->only(['search', 'warehouse_id', 'per_page']),
        ]);
    }

    public function store(Request $request)
    {
        // 兼容前端不同的參數命名 (from/source, to/target)
        $fromId = $request->input('from_warehouse_id') ?? $request->input('sourceWarehouseId');
        $toId = $request->input('to_warehouse_id') ?? $request->input('targetWarehouseId');
        
        $validated = $request->validate([
            'from_warehouse_id' => 'required_without:sourceWarehouseId|exists:warehouses,id',
            'to_warehouse_id' => 'required_without:targetWarehouseId|exists:warehouses,id|different:from_warehouse_id',
            'transit_warehouse_id' => 'nullable|exists:warehouses,id',
            'remarks' => 'nullable|string',
            'notes' => 'nullable|string',
            'instant_post' => 'boolean',
            // 支援單筆商品直接建立 (撥補單模式)
            'product_id' => 'nullable|exists:products,id',
            'quantity' => 'nullable|numeric|min:0.01',
            'batch_number' => 'nullable|string',
        ]);

        $remarks = $validated['remarks'] ?? $validated['notes'] ?? null;
        $transitWarehouseId = $validated['transit_warehouse_id'] ?? null;

        $order = $this->transferService->createOrder(
            $fromId,
            $toId,
            $remarks,
            auth()->id(),
            $transitWarehouseId
        );

        // 手動發送「已建立」日誌，因為服務層使用了 saveQuietly 抑制自動日誌
        activity()
            ->performedOn($order)
            ->causedBy(auth()->id())
            ->event('created')
            ->withProperties([
                'attributes' => [
                    'doc_no' => $order->doc_no,
                    'from_warehouse_id' => $order->from_warehouse_id,
                    'to_warehouse_id' => $order->to_warehouse_id,
                    'transit_warehouse_id' => $order->transit_warehouse_id,
                    'remarks' => $order->remarks,
                    'status' => $order->status,
                    'created_by' => $order->created_by,
                ]
            ])
            ->log('created');
        
        if ($request->input('instant_post') === true) {
            try {
                $this->transferService->dispatch($order, auth()->id());
                    
                return redirect()->back()->with('success', '撥補成功，庫存已更新');
            } catch (\Exception $e) {
                return redirect()->back()->withErrors(['items' => $e->getMessage()]);
            }
        }

        return redirect()->route('inventory.transfer.show', [$order->id])
            ->with('success', '已建立調撥單');
    }

    public function show(InventoryTransferOrder $order)
    {
        $order->load(['items.product.baseUnit', 'fromWarehouse', 'toWarehouse', 'transitWarehouse', 'createdBy', 'postedBy', 'dispatchedBy', 'receivedBy', 'storeRequisition']);

        $orderData = [
            'id' => (string) $order->id,
            'doc_no' => $order->doc_no,
            'from_warehouse_id' => (string) $order->from_warehouse_id,
            'from_warehouse_name' => $order->fromWarehouse->name,
            'from_warehouse_default_transit' => $order->fromWarehouse->default_transit_warehouse_id ? (string)$order->fromWarehouse->default_transit_warehouse_id : null,
            'to_warehouse_id' => (string) $order->to_warehouse_id,
            'to_warehouse_name' => $order->toWarehouse->name,
            'to_warehouse_type' => $order->toWarehouse->type->value,
            // 在途倉資訊
            'transit_warehouse_id' => $order->transit_warehouse_id ? (string) $order->transit_warehouse_id : null,
            'transit_warehouse_name' => $order->transitWarehouse?->name,
            'transit_warehouse_plate' => $order->transitWarehouse?->license_plate,
            'transit_warehouse_driver' => $order->transitWarehouse?->driver_name,
            'status' => $order->status,
            'remarks' => $order->remarks,
            'created_at' => $order->created_at->format('Y-m-d H:i'),
            'created_by' => $order->createdBy?->name,
            'posted_at' => $order->posted_at?->format('Y-m-d H:i'),
            'posted_by' => $order->postedBy?->name,
            'dispatched_at' => $order->dispatched_at?->format('Y-m-d H:i'),
            'dispatched_by' => $order->dispatchedBy?->name,
            'received_at' => $order->received_at?->format('Y-m-d H:i'),
            'received_by' => $order->receivedBy?->name,
            'requisition' => $order->storeRequisition ? [
                'id' => (string) $order->storeRequisition->id,
                'doc_no' => $order->storeRequisition->doc_no,
            ] : null,
            'items' => $order->items->map(function ($item) use ($order) {
                $stock = Inventory::where('warehouse_id', $order->from_warehouse_id)
                    ->where('product_id', $item->product_id)
                    ->where('batch_number', $item->batch_number)
                    ->first();

                return [
                    'id' => (string) $item->id,
                    'product_id' => (string) $item->product_id,
                    'product_name' => $item->product->name,
                    'product_code' => $item->product->code,
                    'batch_number' => $item->batch_number,
                    'expiry_date' => $stock && $stock->expiry_date ? $stock->expiry_date->format('Y-m-d') : null,
                    'unit' => $item->product->baseUnit?->name,
                    'quantity' => (float) $item->quantity,
                    'position' => $item->position,
                    'max_quantity' => $item->snapshot_quantity ? (float) $item->snapshot_quantity : ($stock ? (float) $stock->quantity : 0.0),
                    'notes' => $item->notes,
                ];
            }),
        ];

        // 取得在途倉庫列表供前端選擇
        $transitWarehouses = Warehouse::where('type', WarehouseType::TRANSIT)
            ->get()
            ->map(fn($w) => [
                'id' => (string) $w->id,
                'name' => $w->name,
                'license_plate' => $w->license_plate,
                'driver_name' => $w->driver_name,
            ]);

        return Inertia::render('Inventory/Transfer/Show', [
            'order' => $orderData,
            'transitWarehouses' => $transitWarehouses,
        ]);
    }

    public function update(Request $request, InventoryTransferOrder $order)
    {
        // 收貨動作：僅限 dispatched 狀態
        if ($request->input('action') === 'receive') {
            if ($order->status !== 'dispatched') {
                return redirect()->back()->with('error', '僅能對已出貨的調撥單進行收貨確認');
            }
            try {
                $this->transferService->receive($order, auth()->id());
                return redirect()->route('inventory.transfer.index')
                    ->with('success', '調撥單已收貨完成');
            } catch (ValidationException $e) {
                return redirect()->back()->withErrors($e->errors());
            } catch (\Exception $e) {
                return redirect()->back()->withErrors(['items' => $e->getMessage()]);
            }
        }

        // 以下操作僅限草稿
        if ($order->status !== 'draft') {
            return redirect()->back()->with('error', '只能修改草稿狀態的單據');
        }

        // 1. 更新在途倉庫（如果前端有傳）
        if ($request->has('transit_warehouse_id')) {
            $order->transit_warehouse_id = $request->input('transit_warehouse_id') ?: null;
        }

        // 2. 先更新資料 (如果請求中包含 items，則先執行儲存)
        $itemsChanged = false;
        if ($request->has('items')) {
            if ($order->storeRequisition()->exists()) {
                return redirect()->back()->with('error', '由叫貨單自動產生的調撥單無法修改明細');
            }
            $validated = $request->validate([
                'items' => 'array',
                'items.*.product_id' => 'required|exists:products,id',
                'items.*.quantity' => 'required|numeric|min:0.01',
                'items.*.batch_number' => 'nullable|string',
                'items.*.position' => 'nullable|string',
                'items.*.notes' => 'nullable|string',
            ]);
            $itemsChanged = $this->transferService->updateItems($order, $validated['items']);
        }

        $remarksChanged = false;
        if ($request->has('remarks')) {
            $remarksChanged = $order->remarks !== $request->input('remarks');
            $order->remarks = $request->input('remarks');
        }

        if ($itemsChanged || $remarksChanged || $order->isDirty()) {
            $order->touch(); 
            $message = '儲存成功';
        } else {
            $message = '資料未變更';
        }

        // 3. 判斷是否需要出貨/過帳
        if ($request->input('action') === 'post') {
            try {
                $this->transferService->dispatch($order, auth()->id());
                $hasTransit = !empty($order->transit_warehouse_id);
                $successMsg = $hasTransit ? '調撥單已出貨，庫存已轉入在途倉' : '調撥單已過帳完成';
                return redirect()->route('inventory.transfer.index')
                    ->with('success', $successMsg);
            } catch (ValidationException $e) {
                return redirect()->back()->withErrors($e->errors());
            } catch (\Exception $e) {
                return redirect()->back()->withErrors(['items' => $e->getMessage()]);
            }
        }

        return redirect()->back()->with('success', $message);
    }

    public function destroy(InventoryTransferOrder $order)
    {
        if ($order->status !== 'draft') {
            return redirect()->back()->with('error', '只能刪除草稿狀態的單據');
        }

        // 刪除前必須先釋放預留庫存
        foreach ($order->items as $item) {
            $inv = Inventory::where('warehouse_id', $order->from_warehouse_id)
                ->where('product_id', $item->product_id)
                ->where('batch_number', $item->batch_number)
                ->first();
            if ($inv) {
                $inv->releaseReservedQuantity($item->quantity);
            }
        }

        $order->items()->delete();
        $order->delete();

        return redirect()->route('inventory.transfer.index')
            ->with('success', '調撥單已刪除');
    }

    /**
     * 獲取特定倉庫的庫存列表 (API) - 保留給前端選擇商品用
     */
    public function getWarehouseInventories(Warehouse $warehouse)
    {
        $inventories = $warehouse->inventories()
            ->with(['product.baseUnit', 'product.category'])
            ->where('quantity', '>', 0) 
            ->get()
            ->map(function ($inv) {
                return [
                    'product_id' => (string) $inv->product_id,
                    'product_name' => $inv->product->name,
                    'product_code' => $inv->product->code,
                    'product_barcode' => $inv->product->barcode,
                    'batch_number' => $inv->batch_number,
                    'quantity' => (float) $inv->quantity,
                    'unit_cost' => (float) $inv->unit_cost,
                    'unit_name' => $inv->product->baseUnit?->name ?? '個',
                    'expiry_date' => $inv->expiry_date ? $inv->expiry_date->format('Y-m-d') : null,
                ];
            });

        return response()->json($inventories);
    }
    public function importItems(Request $request, InventoryTransferOrder $order)
    {
        if ($order->status !== 'draft') {
            return redirect()->back()->with('error', '只能在草稿狀態下匯入明細');
        }

        $request->validate([
            'file' => 'required|file|mimes:xlsx,xls,csv',
        ]);

        try {
            \Maatwebsite\Excel\Facades\Excel::import(new \App\Modules\Inventory\Imports\InventoryTransferItemImport($order), $request->file('file'));
            return redirect()->back()->with('success', '匯入成功');
        } catch (\Exception $e) {
            return redirect()->back()->with('error', '匯入失敗：' . $e->getMessage());
        }
    }

    public function template()
    {
        return \Maatwebsite\Excel\Facades\Excel::download(
            new \App\Modules\Inventory\Exports\InventoryTransferTemplateExport(),
            '調撥單明細匯入範本.xlsx'
        );
    }
}

