<?php

namespace App\Http\Controllers;

use App\Models\Product;
use App\Models\Warehouse;
use App\Models\StockBatch;
use App\Models\StockMovement;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;

class InventoryTransferController extends Controller
{
    public function index()
    {
        // Shows the history of all transfers (In and Out)
        $transfers = StockMovement::where('company_id', Auth::user()->current_company_id)
            ->whereIn('type', ['transfer_in', 'transfer_out'])
            ->with(['product', 'warehouse'])
            ->latest()
            ->paginate(30);

        return view('inventory.transfers.index', compact('transfers'));
    }

    public function create()
    {
        $companyId = Auth::user()->current_company_id;
        $products = Product::where('company_id', $companyId)->get();
        $warehouses = Warehouse::where('company_id', $companyId)->get();

        return view('inventory.transfers.create', compact('products', 'warehouses'));
    }

    public function store(Request $request)
    {
        $request->validate([
            'product_id' => 'required|exists:products,id',
            'from_warehouse_id' => 'required|exists:warehouses,id',
            'to_warehouse_id' => 'required|exists:warehouses,id|different:from_warehouse_id',
            'quantity' => 'required|numeric|min:0.01',
            'date' => 'required|date',
        ]);

        return DB::transaction(function () use ($request) {
            $product = Product::findOrFail($request->product_id);
            $qtyToMove = $request->quantity;
            $ref = 'TRF-' . strtoupper(Str::random(6));
            $companyId = Auth::user()->current_company_id;

            // 1. Identify FIFO batches in the SOURCE warehouse
            $batches = StockBatch::where('product_id', $product->id)
                ->where('warehouse_id', $request->from_warehouse_id)
                ->where('remaining_qty', '>', 0)
                ->orderBy('purchase_date', 'asc')
                ->get();

            if ($batches->sum('remaining_qty') < $qtyToMove) {
                return back()->with('error', 'Insufficient stock in the source warehouse.');
            }

            foreach ($batches as $batch) {
                if ($qtyToMove <= 0) break;

                $take = min($batch->remaining_qty, $qtyToMove);

                // 2. Reduce qty in the Source Batch
                $batch->decrement('remaining_qty', $take);

                // 3. Create a mirror Batch in the Destination (Preserving original cost/date)
                StockBatch::create([
                    'company_id' => $companyId,
                    'warehouse_id' => $request->to_warehouse_id,
                    'product_id' => $product->id,
                    'purchase_qty' => $take,
                    'remaining_qty' => $take,
                    'unit_cost' => $batch->unit_cost,
                    'purchase_date' => $batch->purchase_date,
                    'reference' => $ref . ' (Ex ' . $batch->reference . ')',
                    'created_by' => Auth::id(),
                ]);

                $qtyToMove -= $take;
            }

            // 4. Record Dual Audit Movements
            // Movement OUT
            StockMovement::create([
                'company_id' => $companyId,
                'warehouse_id' => $request->from_warehouse_id,
                'product_id' => $product->id,
                'type' => 'transfer_out',
                'reference' => $ref,
                'quantity' => -$request->quantity,
                'balance_after' => $this->getWHBalance($product->id, $request->from_warehouse_id),
                'description' => "Transferred to " . Warehouse::find($request->to_warehouse_id)->name,
                'created_by' => Auth::id(),
            ]);

            // Movement IN
            StockMovement::create([
                'company_id' => $companyId,
                'warehouse_id' => $request->to_warehouse_id,
                'product_id' => $product->id,
                'type' => 'transfer_in',
                'reference' => $ref,
                'quantity' => $request->quantity,
                'balance_after' => $this->getWHBalance($product->id, $request->to_warehouse_id),
                'description' => "Transferred from " . Warehouse::find($request->from_warehouse_id)->name,
                'created_by' => Auth::id(),
            ]);

            return redirect()->route('inventory.transfers.index')->with('success', 'Stock transfer completed.');
        });
    }

    private function getWHBalance($productId, $warehouseId)
    {
        return StockBatch::where('product_id', $productId)
            ->where('warehouse_id', $warehouseId)
            ->sum('remaining_qty');
    }
}