<?php

namespace App\Modules\Inventory\Controllers;

use App\Http\Controllers\Controller;
use App\Modules\Inventory\Models\InventoryAdjustDoc;
use App\Modules\Inventory\Models\InventoryCountDoc;
use App\Modules\Inventory\Models\Warehouse;
use App\Modules\Inventory\Services\AdjustService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;

class AdjustDocController extends Controller
{
    protected $adjustService;

    public function __construct(AdjustService $adjustService)
    {
        $this->adjustService = $adjustService;
    }

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

        // 搜尋
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('doc_no', 'like', "%{$search}%")
                  ->orWhere('reason', 'like', "%{$search}%")
                  ->orWhere('remarks', 'like', "%{$search}%");
            });
        }

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

        $perPage = $request->input('per_page', 10);
        $docs = $query->orderByDesc('created_at')
            ->paginate($perPage)
            ->withQueryString()
            ->through(function ($doc) {
                return [
                    'id' => (string) $doc->id,
                    'doc_no' => $doc->doc_no,
                    'status' => $doc->status,
                    'warehouse_name' => $doc->warehouse->name,
                    'reason' => $doc->reason,
                    'created_at' => $doc->created_at->format('Y-m-d H:i'),
                    'posted_at' => $doc->posted_at ? $doc->posted_at->format('Y-m-d H:i') : '-',
                    'created_by' => $doc->createdBy?->name,
                    'remarks' => $doc->remarks,
                ];
            });

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

    public function store(Request $request)
    {
        // 模式 1: 從盤點單建立
        if ($request->filled('count_doc_id')) {
            $countDoc = InventoryCountDoc::findOrFail($request->count_doc_id);
            if ($countDoc->status !== 'completed') {
                $errorMsg = $countDoc->status === 'no_adjust' 
                    ? '此盤點單無庫存差異，無需建立盤調單' 
                    : '只有已完成盤點的單據可以建立盤調單';
                return redirect()->back()->with('error', $errorMsg);
            }
            
            // 檢查是否已存在對應的盤調單 (避免重複建立)
            if (InventoryAdjustDoc::where('count_doc_id', $countDoc->id)->exists()) {
                return redirect()->back()->with('error', '此盤點單已建立過盤調單');
            }

            $doc = $this->adjustService->createFromCountDoc($countDoc, auth()->id());
                
            return redirect()->route('inventory.adjust.show', [$doc->id])
                ->with('success', '已從盤點單生成盤調單');
        }

        // 模式 2: 一般手動調整 (保留原始邏輯但更新訊息)
        $validated = $request->validate([
            'warehouse_id' => 'required',
            'reason' => 'required|string',
            'remarks' => 'nullable|string',
        ]);

        $doc = $this->adjustService->createDoc(
            $validated['warehouse_id'],
            $validated['reason'],
            $validated['remarks'],
            auth()->id()
        );

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

    /**
     * API: 獲取可盤調的已完成盤點單 (支援掃描單號)
     */
    public function getPendingCounts(Request $request)
    {
        $query = InventoryCountDoc::where('status', 'completed')
            ->whereNotExists(function ($query) {
                $query->select(DB::raw(1))
                    ->from('inventory_adjust_docs')
                    ->whereColumn('inventory_adjust_docs.count_doc_id', 'inventory_count_docs.id');
            });

        if ($request->filled('search')) {
            $search = $request->search;
            $query->where('doc_no', 'like', "%{$search}%");
        }

        $counts = $query->limit(10)->get()->map(function($c) {
            return [
                'id' => (string)$c->id,
                'doc_no' => $c->doc_no,
                'warehouse_name' => $c->warehouse->name,
                'completed_at' => $c->completed_at->format('Y-m-d H:i'),
            ];
        });

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

    public function update(Request $request, InventoryAdjustDoc $doc)
    {
        $action = $request->input('action', 'update');

        if ($action === 'post') {
            if ($doc->status !== 'draft') {
                return redirect()->back()->with('error', '只有草稿狀態的單據可以過帳');
            }
            $this->adjustService->post($doc, auth()->id());
            return redirect()->back()->with('success', '單據已過帳');
        }

        if ($action === 'void') {
            if ($doc->status !== 'draft') {
                return redirect()->back()->with('error', '只有草稿狀態的單據可以作廢');
            }
            $this->adjustService->void($doc, auth()->id());
            return redirect()->back()->with('success', '單據已作廢');
        }

        // 一般更新 (更新品項與基本資訊)
        if ($doc->status !== 'draft') {
            return redirect()->back()->with('error', '只有草稿狀態的單據可以修改');
        }

        $request->validate([
            'reason' => 'required|string',
            'remarks' => 'nullable|string',
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required',
            'items.*.adjust_qty' => 'required|numeric',
        ]);

        $doc->update([
            'reason' => $request->reason,
            'remarks' => $request->remarks,
        ]);

        $this->adjustService->updateItems($doc, $request->items);

        return redirect()->back()->with('success', '單據已更新');
    }

    public function show(InventoryAdjustDoc $doc)
    {
        $doc->load(['items.product.baseUnit', 'createdBy', 'postedBy', 'warehouse', 'countDoc']);

        // Pre-fetch relevant Inventory information (mainly for expiry date)
        $inventoryMap = \App\Modules\Inventory\Models\Inventory::withTrashed()
            ->where('warehouse_id', $doc->warehouse_id)
            ->whereIn('product_id', $doc->items->pluck('product_id'))
            ->whereIn('batch_number', $doc->items->pluck('batch_number'))
            ->get()
            ->mapWithKeys(function ($inv) {
                return [$inv->product_id . '-' . $inv->batch_number => $inv];
            });

        $docData = [
            'id' => (string) $doc->id,
            'doc_no' => $doc->doc_no,
            'warehouse_id' => (string) $doc->warehouse_id,
            'warehouse_name' => $doc->warehouse->name,
            'status' => $doc->status,
            'reason' => $doc->reason,
            'remarks' => $doc->remarks,
            'created_at' => $doc->created_at->format('Y-m-d H:i'),
            'created_by' => $doc->createdBy?->name,
            'count_doc_id' => $doc->count_doc_id ? (string)$doc->count_doc_id : null,
            'count_doc_no' => $doc->countDoc?->doc_no,
            'items' => $doc->items->map(function ($item) use ($inventoryMap) {
                $inv = $inventoryMap->get($item->product_id . '-' . $item->batch_number);
                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' => $inv && $inv->expiry_date ? $inv->expiry_date->format('Y-m-d') : null,
                    'unit' => $item->product->baseUnit?->name,
                    'qty_before' => (float) $item->qty_before,
                    'adjust_qty' => (float) $item->adjust_qty,
                    'notes' => $item->notes,
                ];
            }),
        ];

        return Inertia::render('Inventory/Adjust/Show', [
            'doc' => $docData,
        ]);
    }

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



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

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