<?php

namespace App\Http\Controllers\Api\V1\Inventory;

use App\Http\Controllers\Controller;
use App\Models\Branch;
use App\Models\BranchProduct;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class ProductStockController extends Controller
{
    /** List all tracked products with their stock levels for a branch. */
    public function index(int $branchId): JsonResponse
    {
        $items = BranchProduct::with('product.category')
            ->where('branch_id', $branchId)
            ->where('track_stock', true)
            ->get()
            ->map(fn ($bp) => $this->format($bp));

        return response()->json(['data' => $items]);
    }

    /** Products whose stock is at or below minimum_stock. */
    public function lowStock(int $branchId): JsonResponse
    {
        $items = BranchProduct::with('product.category')
            ->where('branch_id', $branchId)
            ->where('track_stock', true)
            ->whereColumn('stock_quantity', '<=', 'minimum_stock')
            ->get()
            ->map(fn ($bp) => $this->format($bp));

        return response()->json(['data' => $items]);
    }

    /** Add stock (purchase / receive). */
    public function addStock(Request $request, int $branchId, int $productId): JsonResponse
    {
        $data = $request->validate([
            'quantity' => 'required|numeric|min:0.01',
            'notes'    => 'nullable|string|max:500',
        ]);

        $bp = BranchProduct::where('branch_id', $branchId)
            ->where('product_id', $productId)
            ->firstOrFail();

        $bp->increment('stock_quantity', $data['quantity']);

        return response()->json(['data' => $this->format($bp->fresh('product.category'))]);
    }

    /** Set stock to an exact value (stocktake / adjustment). */
    public function adjustStock(Request $request, int $branchId, int $productId): JsonResponse
    {
        $data = $request->validate([
            'quantity' => 'required|numeric|min:0',
            'notes'    => 'nullable|string|max:500',
        ]);

        $bp = BranchProduct::where('branch_id', $branchId)
            ->where('product_id', $productId)
            ->firstOrFail();

        $bp->update(['stock_quantity' => $data['quantity']]);

        return response()->json(['data' => $this->format($bp->fresh('product.category'))]);
    }

    /** Update track_stock, minimum_stock, stock_unit for a product. */
    public function updateSettings(Request $request, int $branchId, int $productId): JsonResponse
    {
        $data = $request->validate([
            'track_stock'   => 'required|boolean',
            'minimum_stock' => 'nullable|numeric|min:0',
            'stock_unit'    => 'nullable|string|max:50',
        ]);

        $bp = BranchProduct::where('branch_id', $branchId)
            ->where('product_id', $productId)
            ->firstOrFail();

        $bp->update([
            'track_stock'   => $data['track_stock'],
            'minimum_stock' => $data['minimum_stock'] ?? $bp->minimum_stock,
            'stock_unit'    => $data['stock_unit']    ?? $bp->stock_unit,
        ]);

        return response()->json(['data' => $this->format($bp->fresh('product.category'))]);
    }

    private function format(BranchProduct $bp): array
    {
        return [
            'product_id'     => $bp->product_id,
            'branch_id'      => $bp->branch_id,
            'product'        => $bp->product,
            'track_stock'    => (bool) $bp->track_stock,
            'stock_quantity' => (float) $bp->stock_quantity,
            'minimum_stock'  => (float) $bp->minimum_stock,
            'stock_unit'     => $bp->stock_unit,
            'is_low_stock'   => $bp->stock_quantity <= $bp->minimum_stock,
            'is_out_of_stock'=> $bp->stock_quantity <= 0,
        ];
    }
}
