<?php

namespace App\Http\Controllers;

use App\Services\AlmacenService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\View\View;

class AlmacenController extends Controller
{
    public function __construct(private readonly AlmacenService $almacenService)
    {
    }

    public function index(): View
    {
        return view('almacen.carga', $this->almacenService->buildCargaData());
    }

    public function inventario(Request $request): View
    {
        $search = trim((string) $request->query('q', ''));
        $itemFilter = trim((string) $request->query('items', 'todos'));

        return view('almacen.inventario', $this->almacenService->buildInventarioData($search, $itemFilter));
    }

    public function updateInventarioItem(Request $request, int $id): RedirectResponse
    {
        $validated = $request->validate([
            '__inventory_action' => ['nullable', 'string'],
            'inventory_item_id' => ['required', 'integer', Rule::in([$id])],
            'cantidad_almacenada' => ['required', 'integer', 'min:0'],
            'cantidad_stock' => ['required', 'integer', 'min:0'],
            'cantidad_entregada' => ['required', 'integer', 'min:0'],
        ]);

        try {
            $result = $this->almacenService->updateInventarioItem($id, $validated, auth()->id());
        } catch (\Throwable $exception) {
            Log::error('Inventory item update failed', [
                'user_id' => auth()->id(),
                'bien_id' => $id,
                'exception' => $exception,
            ]);

            return redirect()
                ->back()
                ->withInput()
                ->with('warning', 'Ocurrio un error interno al actualizar el item del inventario. Intente nuevamente.');
        }

        if (! ($result['ok'] ?? false)) {
            return redirect()
                ->back()
                ->withInput()
                ->with('warning', (string) ($result['warning'] ?? 'No se pudo actualizar el item del inventario.'));
        }

        return redirect()
            ->back()
            ->with('status', (string) ($result['status'] ?? 'Item de inventario actualizado correctamente.'));
    }

    public function destroyInventarioItem(int $id): RedirectResponse
    {
        try {
            $result = $this->almacenService->destroyInventarioItem($id, auth()->id());
        } catch (\Throwable $exception) {
            Log::error('Inventory item delete failed', [
                'user_id' => auth()->id(),
                'bien_id' => $id,
                'exception' => $exception,
            ]);

            return redirect()
                ->back()
                ->with('warning', 'Ocurrio un error interno al eliminar el item del inventario. Intente nuevamente.');
        }

        if (! ($result['ok'] ?? false)) {
            return redirect()
                ->back()
                ->with('warning', (string) ($result['warning'] ?? 'No se pudo eliminar el item del inventario.'));
        }

        return redirect()
            ->back()
            ->with('status', (string) ($result['status'] ?? 'Item eliminado del inventario.'));
    }

    public function actualizar(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'items' => ['required', 'array', 'min:1'],
            'items.*.codigo' => ['required', 'string', 'max:50'],
            'items.*.descripcion' => ['required', 'string', 'max:200'],
            'items.*.tipo' => ['required', 'string', 'max:100'],
            'items.*.almacenado' => ['nullable', 'string', 'max:100'],
            'items.*.stock' => ['nullable', 'string', 'max:100'],
            'items.*.cantidad_almacenado' => ['required', 'integer'],
            'items.*.cantidad_stock' => ['required', 'integer'],
            'items.*.observacion' => ['nullable', 'string', 'max:500'],
        ]);

        try {
            $result = $this->almacenService->actualizar($validated, auth()->id());
        } catch (\Throwable $exception) {
            Log::error('Almacen update transaction failed', [
                'user_id' => auth()->id(),
                'exception' => $exception,
            ]);

            return redirect()
                ->route('almacen.index')
                ->withInput()
                ->with('warning', 'Ocurrio un error interno al actualizar el almacen. Intente nuevamente.');
        }

            if (! ($result['ok'] ?? false)) {
                return redirect()
                ->route('almacen.index')
                ->withInput()
                ->with('warning', (string) ($result['warning'] ?? 'No se pudo procesar la solicitud.'));
            }

            $items = $result['items'];
            $resultadoItems = $result['resultadoItems'];
            $contProcesados = (int) $result['contProcesados'];
            $contOmitidos = (int) $result['contOmitidos'];
            $numeroOperacion = (int) $result['numeroOperacion'];

        return redirect()
            ->route('almacen.index')
            ->with('status', 'Listo. ' . $contProcesados . ' elementos fueron actualizados correctamente y ' . $contOmitidos . ' fueron omitidos por error en las cantidades a modificar.')
            ->with('operacion_resultado', [
                'numero' => $numeroOperacion,
                'total_items' => $items->count(),
                'procesados' => $contProcesados,
                'omitidos' => $contOmitidos,
                'items' => $resultadoItems,
            ])
            ->with('clear_almacen_cart', true);
    }
}