<?php

namespace App\Http\Controllers\Admin;

use App\Actions\Inventory\ExportStockLevels;
use App\Http\Controllers\Concerns\RespondsJsonOrRedirect;
use App\Http\Controllers\Controller;
use App\Models\StockLevel;
use App\Models\Store;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

/**
 * Stock levels — per-store list of every product's on-hand quantity.
 * Read-only here, except for the reorder-level override which is the
 * one field the user can edit inline. Real stock changes happen via
 * stock adjustments.
 *
 * Gated by `products.view` (read) / `products.adjust_stock` (the
 * reorder edit). Honors the active store from the store switcher when
 * no explicit `store_id` filter is set.
 */
class StockLevelController extends Controller
{
    use RespondsJsonOrRedirect;

    public function index(Request $request): View
    {
        $this->authorize('viewAny', StockLevel::class);

        $storeId = enforce_store_access($request->integer('store_id') ?: current_store_id());
        $q       = trim((string) $request->query('q', ''));

        $query = StockLevel::query()
            ->with(['product:id,sku,name,unit_id,reorder_level', 'product.unit:id,code,name', 'variant:id,sku,attributes', 'store:id,code,name'])
            ->when($storeId, fn ($qb) => $qb->where('store_id', $storeId))
            ->when($q !== '', function ($qb) use ($q) {
                $qb->whereHas('product', function ($pq) use ($q) {
                    $pq->where('name', 'like', "%{$q}%")
                       ->orWhere('sku', 'like', "%{$q}%")
                       ->orWhere('barcode', 'like', "%{$q}%");
                });
            })
            ->orderByDesc('last_movement_at');

        // Server-side: only the filter (store, search) narrows the rows.
        // Pagination is client-side via the data-table mixin, matching
        // the rest of the admin (Categories, Products, etc.).
        $levels = $query->get();
        $stores = accessible_stores();

        $trimQty = fn ($v) => rtrim(rtrim(number_format((float) $v, 4, '.', ''), '0'), '.') ?: '0';
        $summaryCards = [
            ['label' => __('inventory.levels.summary.items'), 'value' => number_format($levels->count())],
            ['label' => __('inventory.levels.summary.units'), 'value' => $trimQty($levels->sum('quantity'))],
            ['label' => __('inventory.levels.summary.value'), 'value' => format_money($levels->sum(fn ($l) => (float) $l->quantity * (float) $l->weighted_average_cost))],
            ['label' => __('inventory.levels.summary.out'),   'value' => number_format($levels->where('quantity', '<=', 0)->count()), 'tone' => 'danger'],
        ];

        return view('admin.inventory.levels.index', [
            'levels'       => $levels,
            'summaryCards' => $summaryCards,
            'stores'       => $stores,
            'storeId'      => $storeId,
            'q'            => $q,
        ]);
    }

    public function updateReorderOverride(Request $request, StockLevel $stockLevel): JsonResponse|RedirectResponse
    {
        $this->authorize('update', $stockLevel);

        $data = $request->validate([
            'reorder_level_override' => ['nullable', 'numeric', 'min:0', 'max:9999999.9999'],
        ]);

        $stockLevel->update([
            'reorder_level_override' => $data['reorder_level_override'] === null || $data['reorder_level_override'] === ''
                ? null
                : $data['reorder_level_override'],
        ]);

        return $this->jsonOrRedirect(
            $request,
            __('inventory.levels.flash.reorder_updated'),
            url()->previous() ?: route('admin.inventory.levels.index'),
        );
    }

    public function export(Request $request, ExportStockLevels $export): \Symfony\Component\HttpFoundation\StreamedResponse
    {
        $this->authorize('viewAny', StockLevel::class);

        $format = $request->query('format', 'csv');
        if (! in_array($format, ['csv', 'xlsx'], true)) {
            abort(422, 'Unsupported export format. Use csv or xlsx.');
        }

        return ($export)($format);
    }
}
