<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Requirement;
use App\Models\CostRequirement;
use Illuminate\Support\Facades\DB;
use App\Models\Store;
use App\Models\User;
use App\Models\Deposit;
use App\Models\Input;

class RequirementController extends Controller
    /**
     * Devuelve datos para selects relacionados (stores, users, deposits, insumos).
     */
  
{
    public function index(Request $request)
    {
        $perPage = $request->get('per_page', 10);
        $search = $request->get('search', '');
        $fechaInicio = $request->get('fecha_inicio');
        $fechaFin = $request->get('fecha_fin');
        $idStore = $request->get('id_store');
        $idUser = $request->get('id_user');
        $sortField = $request->get('sort_field', 'id');
        $sortDirection = $request->get('sort_direction', 'desc');
    
        $query = Requirement::with(['store', 'user', 'deposit']);
    
        if ($search) {
            $query->where('codigo', 'like', "%{$search}%");
        }
        if ($idStore) {
            $query->where('id_store', $idStore);
        }
        if ($idUser) {
            $query->where('id_user', $idUser);
        }

        // Ordenamiento con soporte para relaciones
        $allowedFields = ['id', 'codigo', 'date', 'status'];
        if (in_array($sortField, $allowedFields)) {
            $query->orderBy($sortField, $sortDirection);
        } elseif ($sortField === 'store.name') {
            $query->join('stores', 'requirements.id_store', '=', 'stores.id')
                  ->orderBy('stores.name', $sortDirection)
                  ->select('requirements.*');
        } elseif ($sortField === 'user.name') {
            $query->join('users', 'requirements.id_user', '=', 'users.id')
                  ->orderBy('users.name', $sortDirection)
                  ->select('requirements.*');
        } elseif ($sortField === 'deposit.name') {
            $query->leftJoin('deposits', 'requirements.id_deposit', '=', 'deposits.id')
                  ->orderBy('deposits.name', $sortDirection)
                  ->select('requirements.*');
        } else {
            $query->orderBy('id', 'desc');
        }
        
        if ($fechaInicio && $fechaFin) {
            $query->whereBetween('date', [$fechaInicio, $fechaFin]);
        } elseif ($fechaInicio) {
            $query->where('date', '>=', $fechaInicio);
        } elseif ($fechaFin) {
            $query->where('date', '<=', $fechaFin);
        }
    
        $requirements = $query->paginate($perPage);
    
        return response()->json([
            'success' => true,
            'requirements' => $requirements
        ]);
    }

    public function store(Request $request)
    {
        $validatedData = $request->validate([
            'date'       => 'required|date',
            'id_store'   => 'required|exists:stores,id',
            'id_user'    => 'required|exists:users,id',
            'id_deposit' => 'nullable|exists:deposits,id',
            'codigo'     => 'required|string|max:255|unique:requirements,codigo',
            'costs'      => 'nullable|array',
            'costs.*.cantidad'      => 'required|string|max:255',
            'costs.*.id_input'      => 'required|integer|exists:inputs,id',
            'costs.*.id_unit'       => 'nullable|integer|exists:unit_measures,id',
            'costs.*.equivale'      => 'nullable|numeric',
        ], [
            'date.required'      => 'La fecha es obligatoria.',
            'id_store.required'  => 'La tienda es obligatoria.',
            'id_user.required'   => 'El usuario es obligatorio.',
            'codigo.required'    => 'El código es obligatorio.',
            'codigo.unique'      => 'El código ya está registrado.',
            'costs.*.cantidad.required'  => 'La cantidad es obligatoria.',
            'costs.*.id_input.required' => 'El insumo es obligatorio.',
        ]);

        DB::beginTransaction();
        try {
            $requirement = Requirement::create($validatedData);
            $requirement->status = 'Pendiente';
            $requirement->save();

            // Guardar costos si existen
            if (!empty($validatedData['costs'])) {
                foreach ($validatedData['costs'] as $cost) {
                    $requirement->costRequirements()->create([
                        'cantidad'        => $cost['cantidad'],
                        'id_input'        => $cost['id_input'],
                        'id_unit'         => $cost['id_unit'] ?? null,
                        'equivale'        => $cost['equivale'] ?? null,
                        'id_requirement'  => $requirement->id,
                    ]);
                }
            }

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Requerimiento creado exitosamente',
                'data' => $requirement->load(['costRequirements', 'store', 'user', 'deposit'])
            ], 201);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Error al crear el requerimiento',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function update(Request $request, $id)
    {
        $requirement = Requirement::findOrFail($id);

        $validatedData = $request->validate([
            'date'       => 'required|date',
            'id_store'   => 'required|exists:stores,id',
            'id_user'    => 'required|exists:users,id',
            'id_deposit' => 'nullable|exists:deposits,id',
            'codigo'     => 'required|string|max:255|unique:requirements,codigo,' . $requirement->id,
            'costs'      => 'nullable|array',
            'costs.*.id'           => 'nullable|exists:cost_requirements,id',
            'costs.*.cantidad'     => 'required|string|max:255',
            'costs.*.id_input'     => 'required|integer|exists:inputs,id',
            'costs.*.id_unit'      => 'nullable|integer|exists:unit_measures,id',
            'costs.*.equivale'     => 'nullable|numeric',
        ], [
            'date.required'      => 'La fecha es obligatoria.',
            'id_store.required'  => 'La tienda es obligatoria.',
            'id_user.required'   => 'El usuario es obligatorio.',
            'codigo.required'    => 'El código es obligatorio.',
            'codigo.unique'      => 'El código ya está registrado.',
            'costs.*.cantidad.required'  => 'La cantidad es obligatoria.',
            'costs.*.id_input.required' => 'El insumo es obligatorio.',
        ]);

        DB::beginTransaction();
        try {
            $requirement->update($validatedData);

            // Sincronizar costos (elimina todos y vuelve a crear)
            if (isset($validatedData['costs'])) {
                $requirement->costRequirements()->delete();
                foreach ($validatedData['costs'] as $costData) {
                    $requirement->costRequirements()->create([
                        'cantidad'      => $costData['cantidad'],
                        'id_input'      => $costData['id_input'],
                        'id_unit'       => $costData['id_unit'] ?? null,
                        'equivale'      => $costData['equivale'] ?? null,
                        'id_requirement'=> $requirement->id,
                    ]);
                }
            }

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Requerimiento actualizado exitosamente',
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Error al actualizar el requerimiento',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function destroy($id)
    {
        //antes de eliminar verificar si el status no es Aprovado
        $requirement = Requirement::findOrFail($id);
        if ($requirement->status === 'Aprobado') {
            return response()->json([
                'success' => false,
                'message' => 'No se puede eliminar un requerimiento aprobado.'
            ], 400);
        }

        $requirement->costRequirements()->delete();
        $requirement->delete();

        return response()->json([
            'success' => true,
            'message' => 'Requerimiento eliminado exitosamente'
        ]);
    }

    public function show($id)
    {
        $requirement = Requirement::with(['costRequirements.input.costInputs.unit','costRequirements.unit','costRequirements.input.unit', 'store', 'user', 'deposit'])->findOrFail($id);

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

    public function selectData()
    {
        return response()->json([
            'success' => true,
            'stores' => Store::all(),
            'users' => User::all(),
            'deposits' => Deposit::all(),
            'insumos' => Input::with(['unit', 'costInputs.unit'])->get()
            // 👆 Esto es clave: traes cada Input con su unidad principal y sus cost_inputs
        ]);
    }

    

    public function exportToExcel($id)
    {
        $requirement = Requirement::with(['store', 'user', 'deposit', 'costRequirements.input'])->findOrFail($id);

        $filePath = storage_path('app/public/reporte-requirement-' . $id . '.xlsx');
        $writer = \Box\Spout\Writer\Common\Creator\WriterEntityFactory::createXLSXWriter();
        $writer->openToFile($filePath);

        // Cabecera con información del requerimiento
        $headerInfo = \Box\Spout\Writer\Common\Creator\WriterEntityFactory::createRowFromArray([
            'INFORMACIÓN DEL REQUERIMIENTO'
        ]);
        $writer->addRow($headerInfo);

        $infoRows = [
            ['ID:', $requirement->id],
            ['Código:', $requirement->codigo ?? '-'],
            ['Fecha:', $requirement->date ?? '-'],
            ['Tienda:', $requirement->store ? $requirement->store->name : '-'],
            ['Usuario:', $requirement->user ? $requirement->user->name : '-'],
            ['Depósito:', $requirement->deposit ? $requirement->deposit->name : '-'],
            [''], // Fila vacía
        ];

        foreach ($infoRows as $rowData) {
            $row = \Box\Spout\Writer\Common\Creator\WriterEntityFactory::createRowFromArray($rowData);
            $writer->addRow($row);
        }

        // Cabecera de la tabla de costos
        $headerRow = \Box\Spout\Writer\Common\Creator\WriterEntityFactory::createRowFromArray([
            'INSUMOS REQUERIDOS'
        ]);
        $writer->addRow($headerRow);

        $costHeaderRow = \Box\Spout\Writer\Common\Creator\WriterEntityFactory::createRowFromArray([
            'ID', 'Insumo', 'Cantidad'
        ]);
        $writer->addRow($costHeaderRow);

        // Datos de los costos
        if ($requirement->costRequirements && count($requirement->costRequirements) > 0) {
            foreach ($requirement->costRequirements as $cost) {
                $row = \Box\Spout\Writer\Common\Creator\WriterEntityFactory::createRowFromArray([
                    $cost->id,
                    $cost->input ? $cost->input->name : '-',
                    $cost->cantidad
                ]);
                $writer->addRow($row);
            }
        } else {
            $emptyRow = \Box\Spout\Writer\Common\Creator\WriterEntityFactory::createRowFromArray([
                '-', 'Sin insumos registrados', '-'
            ]);
            $writer->addRow($emptyRow);
        }

        $writer->close();
        return response()->download($filePath, 'Requerimiento_' . $requirement->codigo . '.xlsx')->deleteFileAfterSend();
    }
}
