<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Http\Traits\HasPagination;
use App\Models\Inventario;
use Illuminate\Http\Request;
use App\Exports\InventariosExport;
use App\Exports\InventarioTemplateExport;
use App\Imports\InventarioImport;
use Barryvdh\DomPDF\Facade\Pdf;
use Maatwebsite\Excel\Facades\Excel;

class InventarioController extends Controller
{
    use HasPagination;

    public function index(Request $request)
    {
        $query = Inventario::with(['almacen', 'articulo.medida']);

        $searchableFields = [
            'id',
            'cantidad',
            'saldo_stock',
            'ubicacion',
            'articulo.codigo',
            'articulo.nombre',
            'articulo.nombre',
            'almacen.nombre_almacen'
        ];

        if ($request->has('sucursal_id')) {
            $sucursalId = $request->sucursal_id;
            $query->whereHas('almacen', function ($q) use ($sucursalId) {
                $q->where('sucursal_id', $sucursalId);
            });
        }

        $query = $this->applySearch($query, $request, $searchableFields);
        $query = $this->applySorting($query, $request, ['id', 'cantidad', 'saldo_stock', 'created_at'], 'id', 'desc');

        return $this->paginateResponse($query, $request, 15, 100);
    }

    public function store(Request $request)
    {
        $request->validate([
            'almacen_id' => 'required|exists:almacenes,id',
            'articulo_id' => 'required|exists:articulos,id',
            'cantidad' => 'required|integer',
            'ubicacion' => 'nullable|string|max:100',
        ]);

        $inventario = Inventario::create($request->all());

        return response()->json($inventario, 201);
    }

    public function show(Inventario $inventario)
    {
        $inventario->load(['almacen', 'articulo.medida']);
        return response()->json($inventario);
    }

    public function update(Request $request, Inventario $inventario)
    {
        $request->validate([
            'almacen_id' => 'required|exists:almacenes,id',
            'articulo_id' => 'required|exists:articulos,id',
            'cantidad' => 'required|integer',
            'ubicacion' => 'nullable|string|max:100',
        ]);

        // IMPORTANTE: Solo actualizar campos que se enviaron explícitamente
        // Esto preserva los datos existentes del servidor que no se están actualizando
        $camposPermitidos = ['almacen_id', 'articulo_id', 'cantidad', 'ubicacion'];
        $data = $request->only($camposPermitidos);

        $inventario->update($data);

        return response()->json($inventario);
    }

    public function destroy(Inventario $inventario)
    {
        $inventario->delete();
        return response()->json(null, 204);
    }

    /**
     * Vista de inventario agrupado por ítem (artículo)
     * Suma las cantidades totales por artículo
     */
    public function porItem(Request $request)
    {
        $inventarios = Inventario::with(['articulo.medida', 'almacen'])
            ->select('articulo_id')
            ->selectRaw('SUM(cantidad) as total_stock')
            ->selectRaw('SUM(saldo_stock) as total_saldo')
            ->groupBy('articulo_id')
            ->get();

        // Cargar información del artículo y almacenes para cada grupo
        $resultado = $inventarios->map(function ($inv) {
            $articulo = $inv->articulo;

            // Obtener almacenes donde hay stock de este artículo
            $almacenesConStock = Inventario::where('articulo_id', $inv->articulo_id)
                ->with('almacen')
                ->get()
                ->map(function ($item) {
                    return [
                        'almacen' => $item->almacen->nombre_almacen ?? 'Sin almacén',
                        'cantidad' => $item->cantidad,
                        'saldo_stock' => $item->saldo_stock
                    ];
                });

            return [
                'articulo' => $articulo,
                'total_stock' => (float) ($inv->total_stock ?? 0),
                'total_saldo' => (float) ($inv->total_saldo ?? 0),
                'almacenes' => $almacenesConStock->map(function ($item) {
                    return [
                        'almacen' => $item['almacen'],
                        'cantidad' => (float) ($item['cantidad'] ?? 0),
                        'saldo' => (float) ($item['saldo_stock'] ?? 0)
                    ];
                })
            ];
        });

        return response()->json([
            'success' => true,
            'data' => $resultado
        ]);
    }

    /**
     * Vista de inventario por lotes (detallado)
     * Muestra cada registro individual como un lote
     */
    public function porLotes(Request $request)
    {
        $query = Inventario::with(['almacen', 'articulo.medida'])
            ->orderBy('created_at', 'desc');

        // Filtro opcional por artículo
        if ($request->has('articulo_id')) {
            $query->where('articulo_id', $request->articulo_id);
        }

        // Filtro opcional por almacén
        if ($request->has('almacen_id')) {
            $query->where('almacen_id', $request->almacen_id);
        }

        $searchableFields = [
            'id',
            'cantidad',
            'saldo_stock',
            'articulo.codigo',
            'articulo.nombre',
            'almacen.nombre_almacen'
        ];

        if ($request->has('sucursal_id')) {
            $sucursalId = $request->sucursal_id;
            $query->whereHas('almacen', function ($q) use ($sucursalId) {
                $q->where('sucursal_id', $sucursalId);
            });
        }

        $query = $this->applySearch($query, $request, $searchableFields);
        $query = $this->applySorting($query, $request, ['id', 'cantidad', 'saldo_stock', 'created_at'], 'created_at', 'desc');

        return $this->paginateResponse($query, $request, 15, 100);
    }
    /**
     * Descarga plantilla de importación de inventario
     */
    public function downloadTemplate()
    {
        return \Maatwebsite\Excel\Facades\Excel::download(new InventarioTemplateExport, 'plantilla_inventario.xlsx');
    }

    /**
     * Importa inventario desde un archivo Excel
     */
    public function importExcel(Request $request)
    {
        $request->validate([
            'file' => 'required|file|mimes:xlsx,xls'
        ]);

        $import = new InventarioImport();
        try {
            // Forzar lectura de todas las filas, incluso las que parecen vacías
            $file = $request->file('file');
            \Log::info("InventarioController - Iniciando importación", [
                'nombre_archivo' => $file->getClientOriginalName(),
                'tamaño' => $file->getSize(),
                'mime_type' => $file->getMimeType()
            ]);
            
            // Intentar leer el archivo para contar filas antes de importar
            try {
                $reader = \Maatwebsite\Excel\Facades\Excel::toArray([], $file);
                $totalFilasEnArchivo = 0;
                if (!empty($reader) && is_array($reader[0])) {
                    $totalFilasEnArchivo = count($reader[0]);
                }
                \Log::info("InventarioController - Total de filas detectadas en archivo (incluyendo encabezado)", [
                    'total_filas_con_encabezado' => $totalFilasEnArchivo,
                    'total_filas_datos_esperadas' => $totalFilasEnArchivo > 0 ? $totalFilasEnArchivo - 1 : 0
                ]);
            } catch (\Exception $e) {
                \Log::warning("InventarioController - No se pudo contar filas antes de importar", [
                    'error' => $e->getMessage()
                ]);
            }
            
            // Forzar lectura de todas las filas, incluso las que parecen vacías
            Excel::import($import, $file, null, \Maatwebsite\Excel\Excel::XLSX, [
                'readOnly' => false,
                'ignoreEmpty' => false,
                'calculate' => false,
            ]);
            \Log::info("InventarioController - Importación completada", [
                'total_rows' => $import->getTotalRows(),
                'imported_count' => $import->getImportedCount(),
                'skipped_count' => $import->getSkippedCount()
            ]);
        } catch (\Maatwebsite\Excel\Validators\ValidationException $e) {
            $failures = $e->failures();
            $errors = [];
            foreach ($failures as $failure) {
                $errors[] = [
                    'fila' => $failure->row(),
                    'atributo' => $failure->attribute(),
                    'errores' => $failure->errors(),
                    'valores' => $failure->values(),
                ];
            }
            return response()->json([
                'message' => 'Error de validación en el archivo',
                'errores' => $errors
            ], 422);
        }

        // Si usa SkipsFailures, los errores no lanzan excepción, se recogen aquí
        $failures = $import->failures();
        $errors = [];
        foreach ($failures as $failure) {
            $errors[] = [
                'fila' => $failure->row(),
                'atributo' => $failure->attribute(),
                'errores' => $failure->errors(),
                'valores' => $failure->values(),
            ];
        }

        return response()->json([
            'message' => count($errors) > 0 ? 'Importación completada con algunos errores' : 'Importación completada exitosamente',
            'total_filas_procesadas' => $import->getTotalRows(),
            'importadas_exitosamente' => $import->getImportedCount(),
            'filas_omitidas' => $import->getSkippedCount(),
            'errores' => $import->getErrorCount(),
            'detalles_errores' => $errors
        ]);
    }

    /**
     * Exporta inventario a Excel
     */
    public function exportExcel()
    {
        try {
            return Excel::download(new InventariosExport, 'inventario.xlsx');
        } catch (\Exception $e) {
            \Log::error('Error al exportar inventario a Excel: ' . $e->getMessage());
            return response()->json([
                'message' => 'Error al exportar Excel: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Exporta inventario a PDF
     */
    public function exportPDF()
    {
        try {
            $inventarios = Inventario::with(['articulo.medida', 'almacen'])->get();
            $pdf = Pdf::loadView('pdf.inventarios', compact('inventarios'));
            $pdf->setPaper('a4', 'landscape');
            return $pdf->download('inventario.pdf');
        } catch (\Exception $e) {
            \Log::error('Error al exportar inventario a PDF: ' . $e->getMessage());
            return response()->json([
                'message' => 'Error al exportar PDF: ' . $e->getMessage()
            ], 500);
        }
    }
}
