<?php

namespace App\Http\Controllers;

use App\Exports\MedicionesExport;
use App\Models\Medicion;
use App\Models\Paciente;
use App\Models\Responsable;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Maatwebsite\Excel\Facades\Excel;

class MedicionController extends Controller
{
    /**
     * Listado de mediciones.
     */
    public function index(Request $request): View
    {
        $mediciones = $this->consultaFiltrada($request)
            ->orderByDesc('fecha_hora')
            ->paginate(20)
            ->withQueryString();

        return view('mediciones.index', [
            'mediciones' => $mediciones,

            'pacientes' => Paciente::orderBy('apellidos')
                ->get(),
        ]);
    }


    /**
     * Formulario para crear una medición.
     */
    public function create(): View
    {
        return view('mediciones.create', [
            'pacientes' => Paciente::where('activo', true)
                ->orderBy('apellidos')
                ->get(),

            'responsables' => Responsable::where('activo', true)
                ->orderBy('nombre_completo')
                ->get(),
        ]);
    }


    /**
     * Guardar una medición.
     */
    public function store(Request $request): RedirectResponse
    {
        $datos = $request->validate([
            'paciente_id' => [
                'required',
                'exists:pacientes,id',
            ],

            'responsable_id' => [
                'required',
                'exists:responsables,id',
            ],

            'tipo' => [
                'required',
                'in:presion,glucosa',
            ],

            'fecha_hora' => [
                'required',
                'date',
            ],

            'presion_sistolica' => [
                'nullable',
                'required_if:tipo,presion',
                'integer',
                'between:40,300',
            ],

            'presion_diastolica' => [
                'nullable',
                'required_if:tipo,presion',
                'integer',
                'between:20,200',
            ],

            'pulso' => [
                'nullable',
                'integer',
                'between:20,250',
            ],

            'glucosa' => [
                'nullable',
                'required_if:tipo,glucosa',
                'numeric',
                'between:20,1000',
            ],

            'momento_glucosa' => [
                'nullable',
                'required_if:tipo,glucosa',
                'in:ayunas,antes_comida,despues_comida,aleatoria',
            ],

            'observaciones' => [
                'nullable',
                'string',
                'max:1000',
            ],
        ]);


        /*
        |--------------------------------------------------------------------------
        | Evitar guardar datos innecesarios
        |--------------------------------------------------------------------------
        */

        if ($datos['tipo'] === 'presion') {

            $datos['glucosa'] = null;
            $datos['momento_glucosa'] = null;

        } else {

            $datos['presion_sistolica'] = null;
            $datos['presion_diastolica'] = null;
            $datos['pulso'] = null;
        }


        Medicion::create($datos);


        return redirect()
            ->route('mediciones.index')
            ->with(
                'mensaje',
                'Medición registrada correctamente.'
            );
    }


    /**
     * Eliminar una medición.
     */
    public function destroy(
        Medicion $medicion
    ): RedirectResponse {

        $medicion->delete();

        return redirect()
            ->route('mediciones.index')
            ->with(
                'mensaje',
                'Medición eliminada correctamente.'
            );
    }


    /*
    |--------------------------------------------------------------------------
    | VISTA PREVIA EXCEL
    |--------------------------------------------------------------------------
    */

    public function previsualizarExcel(Request $request): View
    {
        $mediciones = $this->consultaFiltrada($request)
            ->orderByDesc('fecha_hora')
            ->get();

        return view('mediciones.excel-preview', [
            'mediciones' => $mediciones,
        ]);
    }


    /*
    |--------------------------------------------------------------------------
    | DESCARGAR EXCEL
    |--------------------------------------------------------------------------
    */

    public function exportarExcel(Request $request)
    {
        return Excel::download(
            new MedicionesExport($request),
            'mediciones_' .
            now()->format('Y-m-d_H-i-s') .
            '.xlsx'
        );
    }


    /*
    |--------------------------------------------------------------------------
    | VISUALIZAR PDF
    |--------------------------------------------------------------------------
    */

    public function exportarPdf(Request $request)
    {
        $mediciones = $this->consultaFiltrada($request)
            ->orderByDesc('fecha_hora')
            ->get();

        $pdf = Pdf::loadView(
            'mediciones.pdf',
            [
                'mediciones' => $mediciones,
            ]
        );

        $pdf->setPaper(
            'a4',
            'landscape'
        );

        return $pdf->stream(
            'mediciones_' .
            now()->format('Y-m-d_H-i-s') .
            '.pdf'
        );
    }


    /*
    |--------------------------------------------------------------------------
    | CONSULTA CON FILTROS
    |--------------------------------------------------------------------------
    |
    | Esta misma consulta se utiliza para:
    |
    | - Grilla
    | - Vista previa Excel
    | - Excel
    | - PDF
    |
    */

    private function consultaFiltrada(
        Request $request
    ): Builder {

        return Medicion::query()

            ->with([
                'paciente',
                'responsable',
            ])


            /*
            |--------------------------------------------------------------------------
            | PACIENTE
            |--------------------------------------------------------------------------
            */

            ->when(
                $request->filled('paciente_id'),

                fn (Builder $query) =>
                    $query->where(
                        'paciente_id',
                        $request->integer('paciente_id')
                    )
            )


            /*
            |--------------------------------------------------------------------------
            | TIPO
            |--------------------------------------------------------------------------
            */

            ->when(
                $request->filled('tipo'),

                fn (Builder $query) =>
                    $query->where(
                        'tipo',
                        $request->input('tipo')
                    )
            )


            /*
            |--------------------------------------------------------------------------
            | FECHA DESDE
            |--------------------------------------------------------------------------
            */

            ->when(
                $request->filled('fecha_desde'),

                fn (Builder $query) =>
                    $query->whereDate(
                        'fecha_hora',
                        '>=',
                        $request->input('fecha_desde')
                    )
            )


            /*
            |--------------------------------------------------------------------------
            | FECHA HASTA
            |--------------------------------------------------------------------------
            */

            ->when(
                $request->filled('fecha_hasta'),

                fn (Builder $query) =>
                    $query->whereDate(
                        'fecha_hora',
                        '<=',
                        $request->input('fecha_hasta')
                    )
            );
    }
}