<?php
namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\InventoryLocation;
use App\Models\Product;
use App\Models\StockAdjustment;
use App\Models\StockMovement;
use App\Models\StockTransfer;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

class InventoryController extends Controller
{
    public function index(): View
    {
        $products = Product::orderBy('stock_quantity')->paginate(20);
        $movements = StockMovement::latest('id')->limit(25)->get();
        $locations = InventoryLocation::orderBy('name')->get();
        return view('admin.inventory.index', compact('products','movements','locations'));
    }

    public function adjustmentForm(): View
    {
        return view('admin.inventory.adjustments', ['products' => Product::orderBy('product_name')->get(), 'adjustments' => StockAdjustment::latest('id')->paginate(20)]);
    }

    public function storeAdjustment(Request $request): RedirectResponse
    {
        $data = $request->validate([
            'adjustment_date' => ['required','date'],
            'product_id' => ['required','exists:products,id'],
            'adjust_qty' => ['required','integer'],
            'reason' => ['required','string','max:120'],
            'notes' => ['nullable','string'],
        ]);

        DB::transaction(function () use ($data) {
            $product = Product::lockForUpdate()->findOrFail($data['product_id']);
            $current = (int) $product->stock_quantity;
            $new = $current + (int) $data['adjust_qty'];
            if ($new < 0) abort(422, 'Stock cannot be negative after adjustment.');
            $product->update(['stock_quantity' => $new]);
            $adj = StockAdjustment::create([
                'adjustment_no' => 'ADJ-' . now()->format('YmdHis'),
                'adjustment_date' => $data['adjustment_date'],
                'product_id' => $product->id,
                'product_code' => $product->product_code,
                'product_name' => $product->product_name,
                'current_qty' => $current,
                'adjust_qty' => $data['adjust_qty'],
                'new_qty' => $new,
                'reason' => $data['reason'],
                'notes' => $data['notes'] ?? null,
                'created_by' => session('admin_id'),
            ]);
            StockMovement::create([
                'product_id' => $product->id,
                'product_code' => $product->product_code,
                'product_name' => $product->product_name,
                'movement_type' => 'adjustment',
                'reference_no' => $adj->adjustment_no,
                'qty' => (int) $data['adjust_qty'],
                'unit_cost' => (float) ($product->original_price ?? 0),
                'unit_price' => (float) ($product->selling_price ?? 0),
                'notes' => $data['reason'],
            ]);
        });

        return back()->with('success', 'Stock adjustment saved successfully.');
    }

    public function transferForm(): View
    {
        return view('admin.inventory.transfers', ['products' => Product::orderBy('product_name')->get(), 'locations' => InventoryLocation::orderBy('name')->get(), 'transfers' => StockTransfer::latest('id')->paginate(20)]);
    }

    public function storeTransfer(Request $request): RedirectResponse
    {
        $data = $request->validate([
            'transfer_date' => ['required','date'],
            'product_id' => ['required','exists:products,id'],
            'from_location' => ['required','string','max:100'],
            'to_location' => ['required','string','max:100','different:from_location'],
            'qty' => ['required','integer','min:1'],
            'notes' => ['nullable','string'],
        ]);
        $product = Product::lockForUpdate()->findOrFail($data['product_id']);
        abort_if((int) $product->stock_quantity < (int) $data['qty'], 422, 'Not enough stock available for transfer.');
        $transferNo = 'TRN-' . now()->format('YmdHis');
        StockTransfer::create([
            'transfer_no' => $transferNo,
            'transfer_date' => $data['transfer_date'],
            'product_id' => $product->id,
            'product_code' => $product->product_code,
            'product_name' => $product->product_name,
            'from_location' => $data['from_location'],
            'to_location' => $data['to_location'],
            'qty' => $data['qty'],
            'notes' => $data['notes'] ?? null,
            'created_by' => session('admin_id'),
        ]);
        StockMovement::create([
            'product_id' => $product->id,
            'product_code' => $product->product_code,
            'product_name' => $product->product_name,
            'movement_type' => 'transfer',
            'reference_no' => $transferNo,
            'qty' => 0,
            'unit_cost' => (float) ($product->original_price ?? 0),
            'unit_price' => (float) ($product->selling_price ?? 0),
            'notes' => 'Transfer: '.$data['from_location'].' -> '.$data['to_location'].' qty '.$data['qty'],
        ]);
        return back()->with('success', 'Stock transfer note saved successfully.');
    }
}
