<?php

namespace App\Modules\Inventory\Controllers;

use App\Http\Controllers\Controller;
use App\Modules\Inventory\Services\GoodsReceiptService;
use App\Modules\Inventory\Services\InventoryService;
use App\Modules\Procurement\Contracts\ProcurementServiceInterface;
use Illuminate\Http\Request;
use Inertia\Inertia;
use App\Modules\Inventory\Models\GoodsReceipt;
use Illuminate\Support\Facades\DB;
use App\Modules\Inventory\Services\DuplicateCheckService;

class GoodsReceiptController extends Controller
{
    protected $goodsReceiptService;
    protected $inventoryService;
    protected $procurementService;
    protected $duplicateCheckService;

    public function __construct(
        GoodsReceiptService $goodsReceiptService,
        InventoryService $inventoryService,
        ProcurementServiceInterface $procurementService,
        DuplicateCheckService $duplicateCheckService
    ) {
        $this->goodsReceiptService = $goodsReceiptService;
        $this->inventoryService = $inventoryService;
        $this->procurementService = $procurementService;
        $this->duplicateCheckService = $duplicateCheckService;
    }

    public function index(Request $request)
    {
        $query = GoodsReceipt::query()
            ->select(['id', 'code', 'type', 'warehouse_id', 'vendor_id', 'received_date', 'status', 'created_at'])
            ->with(['warehouse'])
            ->withSum('items', 'total_amount');

        // 關鍵字搜尋（單號）
        if ($request->filled('search')) {
            $search = $request->input('search');
            $query->where('code', 'like', "%{$search}%");
        }

        // 狀態篩選
        if ($request->filled('status') && $request->input('status') !== 'all') {
            $query->where('status', $request->input('status'));
        }

        // 倉庫篩選
        if ($request->filled('warehouse_id') && $request->input('warehouse_id') !== 'all') {
            $query->where('warehouse_id', $request->input('warehouse_id'));
        }

        // 日期範圍篩選
        if ($request->filled('date_start')) {
            $query->whereDate('received_date', '>=', $request->input('date_start'));
        }
        if ($request->filled('date_end')) {
            $query->whereDate('received_date', '<=', $request->input('date_end'));
        }

        // 每頁筆數
        $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;
        }

        $receipts = $query->orderBy('created_at', 'desc')
            ->paginate($perPage)
            ->withQueryString();

        // Manual Hydration for Vendors (Cross-Module)
        $vendorIds = collect($receipts->items())->pluck('vendor_id')->unique()->filter()->toArray();
        $vendors = $this->procurementService->getVendorsByIds($vendorIds)->keyBy('id');

        $receipts->getCollection()->transform(function ($receipt) use ($vendors) {
            $receipt->vendor = $vendors->get($receipt->vendor_id);
            return $receipt;
        });

        // 取得倉庫列表用於篩選
        $warehouses = $this->inventoryService->getAllWarehouses();

        return Inertia::render('Inventory/GoodsReceipt/Index', [
            'receipts' => $receipts,
            'filters' => $request->only(['search', 'status', 'warehouse_id', 'date_start', 'date_end', 'per_page']),
            'warehouses' => $warehouses,
        ]);
    }

    public function show(Request $request, $id)
    {
        $receipt = GoodsReceipt::with([
            'warehouse',
            'items.product.category',
            'items.product.baseUnit'
        ])->findOrFail($id);

        // Manual Hydration for Vendor (Cross-Module)
        if ($receipt->vendor_id) {
            $receipt->vendor = $this->procurementService->getVendorsByIds([$receipt->vendor_id])->first();
        }

        // 手動計算統計資訊 (如果 Model 沒有定義對應的 Attribute)
        $receipt->items_sum_total_amount = $receipt->items->sum('total_amount');

        return Inertia::render('Inventory/GoodsReceipt/Show', [
            'receipt' => $receipt,
            'navigation' => [
                'from' => $request->query('from'),
                'from_id' => $request->query('from_id'),
                'from_label' => $request->query('from_label'),
            ]
        ]);
    }

    public function create()
    {
        // 取得待進貨的採購單列表（用於標準採購類型選擇）
        $pendingPOs = $this->procurementService->getPendingPurchaseOrders();
        
        // 提取所有產品 ID 以便跨模組水和資料
        $productIds = $pendingPOs->flatMap(fn($po) => $po->items->pluck('product_id'))->unique()->filter()->toArray();
        $products = $this->inventoryService->getProductsByIds($productIds)->keyBy('id');

        // 處理採購單資料，計算剩餘可收貨數量
        $formattedPOs = $pendingPOs->map(function ($po) use ($products) {
            return [
                'id' => $po->id,
                'code' => $po->code,
                'status' => $po->status,
                'supplierId' => $po->vendor_id, // Alias for frontend
                'vendor_id' => $po->vendor_id,
                'vendor_name' => $po->vendor?->name ?? '',
                'warehouse_id' => $po->warehouse_id,
                'order_date' => $po->order_date,
                'items' => $po->items->map(function ($item) use ($products) {
                    $product = $products->get($item->product_id);
                    $remaining = max(0, $item->quantity - ($item->received_quantity ?? 0));
                    
                    // 獲取單位名稱
                    $baseUnitName = $product?->baseUnit?->name ?? '個';
                    $largeUnitName = $product?->largeUnit?->name ?? '';
                    
                    // 判斷當前採購使用的單位 (這需要從 PurchaseOrderItem 獲取 unit_id 並與產品的 large_unit_id 比較)
                    $selectedUnit = 'base';
                    if ($item->unit_id && $product && $item->unit_id == $product->large_unit_id) {
                        $selectedUnit = 'large';
                    }

                    return [
                        'id' => $item->id,
                        'productId' => $item->product_id, // Alias for frontend
                        'product_id' => $item->product_id,
                        'productName' => $product?->name ?? '', // Alias for frontend
                        'product_name' => $product?->name ?? '',
                        'product_code' => $product?->code ?? '',
                        'unit' => $product?->baseUnit?->name ?? '個', // 預設顯示文字
                        'selectedUnit' => $selectedUnit,
                        'base_unit_id' => $product?->base_unit_id,
                        'base_unit_name' => $baseUnitName,
                        'large_unit_id' => $product?->large_unit_id,
                        'large_unit_name' => $largeUnitName,
                        'conversion_rate' => $product?->conversion_rate ?? 1,
                        'quantity' => $item->quantity,
                        'received_quantity' => $item->received_quantity ?? 0,
                        'remaining' => $remaining,
                        'unitPrice' => $item->unit_price, // Alias for frontend
                        'unit_price' => $item->unit_price,
                    ];
                })->filter(fn($item) => $item['remaining'] > 0)->values(),
            ];
        })->filter(fn($po) => $po['items']->count() > 0)->values();

        // 取得所有廠商列表（用於雜項入庫/其他類型選擇）
        $vendors = $this->procurementService->getAllVendors();

        return Inertia::render('Inventory/GoodsReceipt/Create', [
            'warehouses' => $this->inventoryService->getAllWarehouses(),
            'pendingPurchaseOrders' => $formattedPOs,
            'vendors' => $vendors,
        ]);
    }

    public function store(Request $request)
    {
        $validated = $request->validate($this->getItemValidationRules());

        try {
            $this->goodsReceiptService->store($request->all());
            return redirect()->route('goods-receipts.index')->with('success', '進貨草稿已建立');
        } catch (\Exception $e) {
            return back()->with('error', $e->getMessage());
        }
    }

    /**
     * 編輯進貨單（僅草稿/退回狀態）
     */
    public function edit(GoodsReceipt $goodsReceipt)
    {
        if (!in_array($goodsReceipt->status, [GoodsReceipt::STATUS_DRAFT, 'rejected'])) {
            return redirect()->route('goods-receipts.show', $goodsReceipt->id)
                ->with('error', '只有草稿或被退回的進貨單可以編輯。');
        }

        // 載入品項與產品資訊
        $goodsReceipt->load('items');

        // 取得品項關聯的商品資訊
        $productIds = $goodsReceipt->items->pluck('product_id')->unique()->toArray();
        $products = $this->inventoryService->getProductsByIds($productIds)->keyBy('id');

        // 如果是標準採購，取得對應採購單的品項，以帶出預定數量與已收數量
        $poItems = collect();
        $po = null;
        if ($goodsReceipt->type === 'standard' && $goodsReceipt->purchase_order_id) {
            $po = clone $this->procurementService->getPurchaseOrdersByIds([$goodsReceipt->purchase_order_id], ['items', 'vendor'])->first();
            if ($po) {
                $poItems = $po->items->keyBy('id');
            }
        }

        // 格式化品項資料
        $formattedItems = $goodsReceipt->items->map(function ($item) use ($products, $poItems) {
            $product = $products->get($item->product_id);
            $poItem = $poItems->get($item->purchase_order_item_id);
            
            // 判斷單位
            $selectedUnit = 'base';
            if ($poItem && $product && $poItem->unit_id && $poItem->unit_id == $product->large_unit_id) {
                $selectedUnit = 'large';
            }

            return [
                'product_id' => $item->product_id,
                'purchase_order_item_id' => $item->purchase_order_item_id,
                'product_name' => $product?->name ?? '',
                'product_code' => $product?->code ?? '',
                'unit' => $poItem && $selectedUnit === 'large' ? ($product?->largeUnit?->name ?? '') : ($product?->baseUnit?->name ?? '個'),
                'selectedUnit' => $selectedUnit,
                'base_unit_id' => $product?->base_unit_id,
                'base_unit_name' => $product?->baseUnit?->name ?? '個',
                'large_unit_id' => $product?->large_unit_id,
                'large_unit_name' => $product?->largeUnit?->name ?? '',
                'conversion_rate' => $product?->conversion_rate ?? 1,
                'quantity_ordered' => $poItem ? $poItem->quantity : null,
                'quantity_received_so_far' => $poItem ? ($poItem->received_quantity ?? 0) : null,
                'quantity_received' => (float) $item->quantity_received,
                'unit_price' => (float) $item->unit_price,
                'subtotal' => (float) $item->total_amount,
                'batch_number' => $item->batch_number ?? '',
                'batchMode' => 'existing',
                'originCountry' => 'TW',
                'expiry_date' => $item->expiry_date ?? '',
            ];
        })->values();

        // 同 create() 一樣傳入所需的 props
        $pendingPOs = $this->procurementService->getPendingPurchaseOrders();
        $productIdsForPOs = $pendingPOs->flatMap(fn($po) => $po->items->pluck('product_id'))->unique()->filter()->toArray();
        $productsForPOs = $this->inventoryService->getProductsByIds($productIdsForPOs)->keyBy('id');

        $formattedPOs = $pendingPOs->map(function ($po) use ($productsForPOs) {
            return [
                'id' => $po->id,
                'code' => $po->code,
                'status' => $po->status,
                'supplierId' => $po->vendor_id,
                'vendor_id' => $po->vendor_id,
                'vendor_name' => $po->vendor?->name ?? '',
                'warehouse_id' => $po->warehouse_id,
                'order_date' => $po->order_date,
                'items' => $po->items->map(function ($item) use ($productsForPOs) {
                    $product = $productsForPOs->get($item->product_id);
                    $remaining = max(0, $item->quantity - ($item->received_quantity ?? 0));
                    
                    $selectedUnit = 'base';
                    if ($item->unit_id && $product && $item->unit_id == $product->large_unit_id) {
                        $selectedUnit = 'large';
                    }

                    return [
                        'id' => $item->id,
                        'productId' => $item->product_id,
                        'product_id' => $item->product_id,
                        'productName' => $product?->name ?? '',
                        'product_name' => $product?->name ?? '',
                        'product_code' => $product?->code ?? '',
                        'unit' => $item->unit_id && $product && $item->unit_id == $product->large_unit_id ? ($product?->largeUnit?->name ?? '') : ($product?->baseUnit?->name ?? '個'),
                        'selectedUnit' => $selectedUnit,
                        'base_unit_id' => $product?->base_unit_id,
                        'base_unit_name' => $product?->baseUnit?->name ?? '個',
                        'large_unit_id' => $product?->large_unit_id,
                        'large_unit_name' => $product?->largeUnit?->name ?? '',
                        'conversion_rate' => $product?->conversion_rate ?? 1,
                        'quantity' => $item->quantity,
                        'received_quantity' => $item->received_quantity ?? 0,
                        'remaining' => $remaining,
                        'unitPrice' => $item->unit_price,
                        'unit_price' => $item->unit_price,
                    ];
                })->filter(fn($item) => $item['remaining'] > 0)->values(),
            ];
        })->filter(fn($po) => $po['items']->count() > 0)->values();

        $vendors = $this->procurementService->getAllVendors();

        // Manual Hydration for Vendor
        $vendor = null;
        if ($goodsReceipt->vendor_id) {
            $vendor = $this->procurementService->getVendorsByIds([$goodsReceipt->vendor_id])->first();
        }

        // 格式化 Purchase Order 給前端顯示
        $formattedPO = null;
        if ($po) {
            $formattedPO = [
                'id' => $po->id,
                'code' => $po->code,
                'status' => $po->status,
                'vendor_id' => $po->vendor_id,
                'vendor_name' => $po->vendor?->name ?? '',
                'warehouse_id' => $po->warehouse_id,
                'order_date' => $po->order_date,
                'items' => $po->items->toArray(), // simplified since we just need items.length for display
            ];
        }

        return Inertia::render('Inventory/GoodsReceipt/Create', [
            'warehouses' => $this->inventoryService->getAllWarehouses(),
            'pendingPurchaseOrders' => $formattedPOs,
            'vendors' => $vendors,
            'receipt' => [
                'id' => $goodsReceipt->id,
                'code' => $goodsReceipt->code,
                'type' => $goodsReceipt->type,
                'warehouse_id' => $goodsReceipt->warehouse_id,
                'vendor_id' => $goodsReceipt->vendor_id,
                'vendor' => $vendor,
                'purchase_order_id' => $goodsReceipt->purchase_order_id,
                'purchase_order' => $formattedPO,
                'received_date' => \Carbon\Carbon::parse($goodsReceipt->received_date)->format('Y-m-d'),
                'remarks' => $goodsReceipt->remarks,
                'items' => $formattedItems,
            ],
        ]);
    }

    /**
     * 更新進貨單
     */
    public function update(Request $request, GoodsReceipt $goodsReceipt)
    {
        $validated = $request->validate($this->getItemValidationRules());

        try {
            $this->goodsReceiptService->update($goodsReceipt, $request->all());
            return redirect()->route('goods-receipts.show', $goodsReceipt->id)->with('success', '進貨單已更新');
        } catch (\Exception $e) {
            return back()->with('error', $e->getMessage());
        }
    }

    /**
     * 取得品項驗證規則
     */
    private function getItemValidationRules(): array
    {
        return [
            'warehouse_id' => 'required|exists:warehouses,id',
            'type' => 'required|in:standard,miscellaneous,other',
            'purchase_order_id' => 'nullable|required_if:type,standard|exists:purchase_orders,id',
            'vendor_id' => 'nullable|integer',
            'received_date' => 'required|date',
            'remarks' => 'nullable|string',
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required|integer|exists:products,id',
            'items.*.purchase_order_item_id' => 'nullable|required_if:type,standard|integer',
            'items.*.quantity_received' => 'required|numeric|min:0',
            'items.*.unit_price' => 'nullable|numeric|min:0',
            'items.*.subtotal' => 'nullable|numeric|min:0',
            'items.*.batch_number' => 'nullable|string',
            'items.*.expiry_date' => 'nullable|date',
            'force' => 'nullable|boolean',
        ];
    }

    /**
     * 預檢重複進貨 API
     */
    public function checkDuplicate(Request $request)
    {
        $result = $this->duplicateCheckService->checkDuplicateReceipt($request->all());
        return response()->json($result);
    }

    public function submit(GoodsReceipt $goodsReceipt)
    {
        if (!auth()->user()->can('goods_receipts.edit')) {
            return back()->with('error', '您沒有權限確認點收');
        }

        try {
            $this->goodsReceiptService->submit($goodsReceipt);
            return back()->with('success', '進貨單已點收完成，庫存已增加並拋轉應付帳款');
        } catch (\Exception $e) {
            return back()->with('error', $e->getMessage());
        }
    }

    // API to search POs
    public function searchPOs(Request $request)
    {
        $search = $request->input('query');
        if (!$search) {
            return response()->json([]);
        }

        $pos = $this->procurementService->searchPendingPurchaseOrders($search);
        
        return response()->json($pos);
    }

    // API to search Products for Manual Entry
    // 支援 query='*' 回傳所有商品（用於 SearchableSelect 下拉選單）
    public function searchProducts(Request $request)
    {
        $search = $request->input('query');
        if (!$search) {
            return response()->json([]);
        }

        // 萬用字元：回傳所有商品
        if ($search === '*') {
            $products = $this->inventoryService->getProductsByName('');
        } else {
            $products = $this->inventoryService->getProductsByName($search);
        }
        
        // Format for frontend
        $mapped = $products->map(function($product) {
            return [
                'id' => $product->id,
                'name' => $product->name,
                'code' => $product->code,
                'unit' => $product->baseUnit?->name ?? '個',
                'price' => $product->purchase_price ?? 0,
            ];
        });

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

    // API to search Vendors
    public function searchVendors(Request $request)
    {
        $search = $request->input('query');
        if (!$search) {
            return response()->json([]);
        }

        $vendors = $this->procurementService->searchVendors($search);
        
        return response()->json($vendors);
    }

    /**
     * 刪除進貨單
     */
    public function destroy(GoodsReceipt $goodsReceipt)
    {
        // 只有有權限的人可以刪除
        if (!auth()->user()->can('goods_receipts.delete')) {
            return redirect()->back()->with('error', '您沒有權限刪除進貨單');
        }

        // 簡單刪除邏輯：刪除進貨單（品項由資料庫級聯刪除或手動處理）
        // 注意：實務上可能需要處理已入庫的庫存回滾，但在這個簡易 ERP 中通常是行政刪除
        $goodsReceipt->delete();

        return redirect()->route('goods-receipts.index')->with('success', '進貨單已刪除');
    }
}
