<?php

namespace App\Http\Controllers;

use App\Models\Grn;
use App\Models\GrnItem;
use App\Models\StockBalance;
use App\Models\StockLedger;
use App\Models\Warehouse;
use App\Models\WarehouseBin;
use App\Services\InventoryService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class WmsDemoController extends Controller
{
    protected $inventoryService;

    public function __construct(InventoryService $inventoryService)
    {
        $this->inventoryService = $inventoryService;
    }

    public function index()
    {
        $warehouses = Warehouse::with('bins')->get();
        $stockBalances = StockBalance::with(['item', 'warehouse', 'bin'])->get();
        $recentLedgerEntries = StockLedger::with(['item', 'bin'])
            ->orderBy('occurred_at', 'desc')
            ->limit(10)
            ->get();

        return view('wms.demo', compact('warehouses', 'stockBalances', 'recentLedgerEntries'));
    }

    public function demoWorkflow()
    {
        try {
            DB::beginTransaction();

            // Get the main warehouse and bins
            $mainWarehouse = Warehouse::where('code', 'MAIN')->first();
            $receiptBin = WarehouseBin::where('warehouse_id', $mainWarehouse->id)
                ->where('type', 'receipt')
                ->first();
            $generalBin = WarehouseBin::where('warehouse_id', $mainWarehouse->id)
                ->where('type', 'general')
                ->first();

            // Find a GRN that can be posted
            $grn = Grn::where('status', 'accepted')
                ->with(['items.purchaseOrderItem.item'])
                ->first();

            // If no warehouse is set, set it to the main warehouse
            if ($grn && !$grn->warehouse_id) {
                $grn->update(['warehouse_id' => $mainWarehouse->id]);
            }

            if (!$grn) {
                return response()->json([
                    'success' => false,
                    'message' => 'No GRN found with accepted status for demo. Please create and accept a GRN first.'
                ]);
            }

            // Step 1: Post GRN to inventory
            $grn->update(['status' => 'posted']);

            // Step 2: Check stock balances after posting
            $stockBalancesAfterPost = StockBalance::where('warehouse_id', $mainWarehouse->id)
                ->where('bin_id', $receiptBin->id)
                ->with(['item'])
                ->get();

            // Step 3: Perform putaway for one item
            $grnItem = $grn->items->first();
            if ($grnItem && $grnItem->accepted_qty > 0) {
                $putawayQty = min($grnItem->accepted_qty, 5); // Putaway 5 units or less
                $this->inventoryService->putaway($grnItem->id, $generalBin->id, $putawayQty);
            }

            // Step 4: Check final stock balances
            $finalStockBalances = StockBalance::where('warehouse_id', $mainWarehouse->id)
                ->with(['item', 'bin'])
                ->get();

            // Step 5: Get recent ledger entries
            $recentLedger = StockLedger::with(['item', 'bin'])
                ->orderBy('occurred_at', 'desc')
                ->limit(5)
                ->get();

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'WMS demo workflow completed successfully',
                'data' => [
                    'grn_number' => $grn->grn_number,
                    'stock_balances_after_post' => $stockBalancesAfterPost,
                    'final_stock_balances' => $finalStockBalances,
                    'recent_ledger_entries' => $recentLedger,
                    'putaway_qty' => $putawayQty ?? 0,
                ]
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Demo workflow failed: ' . $e->getMessage()
            ]);
        }
    }

    public function getStockBalances()
    {
        $stockBalances = StockBalance::with(['item', 'warehouse', 'bin'])
            ->where('on_hand_qty', '>', 0)
            ->get();

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

    public function getLedgerEntries()
    {
        $ledgerEntries = StockLedger::with(['item', 'bin'])
            ->orderBy('occurred_at', 'desc')
            ->limit(20)
            ->get();

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