<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Unidade;
use App\Models\UserMonitoreo;
use App\Models\Puesto;
use App\Models\Misione;
use App\Models\MisioneItem;
use App\Models\Persona;
use Carbon\Carbon;
use DB;
use Illuminate\Support\Facades\Storage;

class UnidadController extends Controller
{
    private array $imageFields = [
        'uni_imagen',
        'uni_img',
        'imagen',
        'image',
        'foto',
        'archivo',
    ];

    private function getUnidadImageFile(Request $request)
    {
        foreach ($this->imageFields as $field) {
            if ($request->hasFile($field)) {
                return $request->file($field);
            }
        }

        return null;
    }

    private function storeUnidadImage(Request $request): ?string
    {
        $image = $this->getUnidadImageFile($request);

        if (!$image || !$image->isValid()) {
            return null;
        }

        $path = $image->store('unidades', 'public');

        return 'storage/' . $path;
    }

    private function deleteUnidadImage(?string $imagePath): void
    {
        if (!$imagePath) {
            return;
        }

        $path = preg_replace('/^\/?storage\//', '', $imagePath);

        if ($path && ($path !== $imagePath || str_starts_with($imagePath, 'unidades/'))) {
            Storage::disk('public')->delete($path);
        }
    }

    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        $search = $request->get("search");
        if (auth()->user()->roles[0]->name == 'Super-Admin' || auth()->user()->roles[0]->name == 'Admin-Dpto-III') {
            $unidades = Unidade::select('unidades.uni_cod', 'unidades.uni_detalle', 'unidades.uni_abrev', 'unidades.uni_codsup', 'unisup.uni_detalle as unisup', 'unidades.uni_fechareg', 'unidades.uni_geojson', 'unidades.uni_latitud', 'unidades.uni_longitud', 'unidades.uni_imagen', 'unidades.uni_estado')
                ->leftJoin('unidades as unisup', 'unisup.uni_cod', '=', 'unidades.uni_codsup')
                ->where(DB::raw("
                                        unidades.uni_detalle || ' ' ||
                                        unidades.uni_abrev || ' ' ||
                                        COALESCE(unisup.uni_detalle, '') || ' ' ||
                                        COALESCE(unisup.uni_abrev, '')
                                    "), 'ilike', "%{$search}%")
                ->whereNull('unidades.uni_codsup')
                ->orderBy("unidades.uni_cod", "desc")->get();
        } elseif (auth()->user()->roles[0]->name == 'G-3') {
            $unidades = Unidade::select('unidades.uni_cod', 'unidades.uni_detalle', 'unidades.uni_abrev', 'unidades.uni_codsup', 'unisup.uni_detalle as unisup', 'unidades.uni_fechareg', 'unidades.uni_geojson', 'unidades.uni_latitud', 'unidades.uni_longitud', 'unidades.uni_imagen', 'unidades.uni_estado')
                ->leftJoin('unidades as unisup', 'unisup.uni_cod', '=', 'unidades.uni_codsup')
                ->where(DB::raw("
                                        unidades.uni_detalle || ' ' ||
                                        unidades.uni_abrev || ' ' ||
                                        COALESCE(unisup.uni_detalle, '') || ' ' ||
                                        COALESCE(unisup.uni_abrev, '')
                                    "), 'ilike', "%{$search}%")
                //->whereNull('unidades.uni_codsup')
                ->where("unidades.uni_cod", auth()->user()->user_uni_cod)
                ->orderBy("unidades.uni_cod", "desc")->get();
        }

        return response()->json([
            "unidades" => $unidades
        ]);
    }
    /*NUEVOS REQUERIMIENTOS*/
    public function listunidadesdependientes(Request $request, $uni_cod)
    {
        $search = $request->get("search");

        $unidades = Unidade::select('unidades.uni_cod', 'unidades.uni_detalle', 'unidades.uni_abrev', 'unidades.uni_codsup', 'unisup.uni_detalle as unisup', 'unidades.uni_fechareg', 'unidades.uni_geojson', 'unidades.uni_latitud', 'unidades.uni_longitud', 'unidades.uni_imagen', 'unidades.uni_estado')
            ->leftJoin('unidades as unisup', 'unisup.uni_cod', '=', 'unidades.uni_codsup')
            ->where(DB::raw("
                                        unidades.uni_detalle || ' ' ||
                                        unidades.uni_abrev || ' ' ||
                                        COALESCE(unisup.uni_detalle, '') || ' ' ||
                                        COALESCE(unisup.uni_abrev, '')
                                    "), 'ilike', "%{$search}%")
            ->where('unidades.uni_codsup', $uni_cod)
            ->orderBy("unidades.uni_cod", "desc")->get();

        return response()->json([
            "unidades" => $unidades
        ]);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        $is_uni_exists = Unidade::where("uni_detalle", $request->uni_detalle)->first();
        if ($is_uni_exists) {
            return response()->json([
                "message" => 403,
                "message_text" => "LA UNIDAD YA EXISTE"
            ]);
        }
        $imagePath = $this->storeUnidadImage($request);

        $unidade = Unidade::create([
            "uni_detalle" => $request->uni_detalle,
            "uni_abrev" => $request->uni_abrev,
            "uni_codsup" => $request->uni_codsup,
            "uni_geojson" => $request->uni_geojson,
            "uni_latitud" => $request->uni_latitud,
            "uni_longitud" => $request->uni_longitud,
            "uni_imagen" => $imagePath,
            "uni_estado" => "A",
            "uni_usuareg" => auth()->user()->id,
            "uni_fechareg" => Date("Y-m-d")
        ]);

        return response()->json([
            "message" => 200,
            "unidade" => $unidade
        ]);
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        $unidade = Unidade::where("uni_cod", $id)
            ->where("uni_estado", "A")
            ->first();

        if (!$unidade) {
            return response()->json([
                "message" => 404,
                "message_text" => "LA UNIDAD NO EXISTE"
            ], 404);
        }

        return response()->json([
            "message" => 200,
            "unidade" => $unidade
        ]);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {
        $is_uni_exists = Unidade::where("uni_detalle", $request->uni_detalle)->where("uni_cod", "<>", $id)->first();
        if ($is_uni_exists) {
            return response()->json([
                "message" => 403,
                "message_text" => "LA UNIDAD YA EXISTE"
            ]);
        }
        $unidade = Unidade::where("uni_cod", $id)->first();
        if (!$unidade) {
            return response()->json([
                "message" => 404,
                "message_text" => "LA UNIDAD NO EXISTE"
            ], 404);
        }

        $imagePath = $this->storeUnidadImage($request);

        $updateData = [
            "uni_detalle" => $request->uni_detalle,
            "uni_abrev" => $request->uni_abrev,
            "uni_codsup" => $request->uni_codsup,
            "uni_geojson" => $request->uni_geojson,
            "uni_latitud" => $request->uni_latitud,
            "uni_longitud" => $request->uni_longitud,
            "uni_usuamod" => auth()->user()->id,
            "uni_fechamod" => Date("Y-m-d")
        ];

        if ($imagePath) {
            $this->deleteUnidadImage($unidade->uni_imagen);
            $updateData["uni_imagen"] = $imagePath;
        }

        $unidade->update($updateData);

        return response()->json([
            "message" => 200,
            "unidade" => $unidade
        ]);
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        $unidade = unidade::where("uni_cod", $id)->first();
        $unidade->uni_estado = "N";
        $unidade->uni_fechabaja = Date("Y-m-d");
        $unidade->uni_usuabaja = auth()->user()->id;
        $unidade->save();

        return response()->json([
            "message" => 200
        ]);
    }

    public function updateLogo(Request $request, string $id)
    {
        $request->validate([
            'logo' => ['required', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'],
        ]);

        $unidade = Unidade::findOrFail($id);
        $imagePath = $this->storeUnidadImage($request);

        if (! $imagePath) {
            return response()->json([
                'message' => 'No se pudo procesar la imagen enviada.',
            ], 422);
        }

        $this->deleteUnidadImage($unidade->uni_imagen);
        $unidade->update([
            'uni_imagen' => $imagePath,
            'uni_usuamod' => auth()->id(),
            'uni_fechamod' => now()->toDateString(),
        ]);

        return response()->json([
            'message' => 200,
            'message_text' => 'Emblema actualizado correctamente.',
            'unidade' => $unidade->fresh(),
        ]);
    }

    public function toggleEstado(string $id)
    {
        $unidade = Unidade::findOrFail($id);
        $activating = $unidade->uni_estado !== 'A';

        $unidade->uni_estado = $activating ? 'A' : 'N';
        $unidade->uni_usuamod = auth()->id();
        $unidade->uni_fechamod = now()->toDateString();
        $unidade->uni_usuabaja = $activating ? null : auth()->id();
        $unidade->uni_fechabaja = $activating ? null : now()->toDateString();
        $unidade->save();

        return response()->json([
            'message' => 200,
            'message_text' => $activating
                ? 'Unidad activada correctamente.'
                : 'Unidad desactivada correctamente.',
            'unidade' => $unidade,
        ]);
    }

    public function getunidades(Request $request)
    {
        $uni_detalle = $request->searchunidade ?? '';
        //return response()->json([ "data" => $uni_detalle]);
        $unidades = Unidade::select("uni_cod", "uni_detalle")
            ->where('uni_detalle', 'ilike', "%{$uni_detalle}%")
            ->where("uni_estado", "A")->get();
        return response()->json($unidades);
    }

    public function mapaunisups()
    {
        if (auth()->user()->roles[0]->name == 'Super-Admin' || auth()->user()->roles[0]->name == 'Admin-Dpto-III') {
            $unidades = Unidade::select('uni_cod', 'uni_abrev', 'uni_geojson', 'uni_latitud', 'uni_longitud', 'uni_codsup', 'uni_imagen')
                ->where('uni_estado', 'A')
                ->get();
            $unisups = Unidade::select('uni_cod', 'uni_abrev', 'uni_geojson', 'uni_latitud', 'uni_longitud', 'uni_imagen')
                ->whereNull('uni_codsup')
                ->where('uni_estado', 'A')
                ->get();
        } elseif (auth()->user()->roles[0]->name == 'G-3') {
            $unidades = Unidade::select('uni_cod', 'uni_abrev', 'uni_geojson', 'uni_latitud', 'uni_longitud', 'uni_codsup', 'uni_imagen')
                ->where('uni_estado', 'A')
                ->where('uni_codsup', auth()->user()->user_uni_cod)
                ->get();

            $unisups = Unidade::select('uni_cod', 'uni_abrev', 'uni_geojson', 'uni_latitud', 'uni_longitud', 'uni_imagen')
                ->whereNull('uni_codsup')
                ->where('uni_estado', 'A')
                ->where('uni_cod', auth()->user()->user_uni_cod)
                ->get();
        } elseif (auth()->user()->roles[0]->name == 'P-3') {
            $unidades = Unidade::select('uni_cod', 'uni_abrev', 'uni_latitud', 'uni_longitud', 'uni_codsup', 'uni_imagen')
                ->where('uni_estado', 'A')
                ->where('uni_cod', auth()->user()->user_uni_cod)
                ->get();

            $unisups = Unidade::select('uni_cod', 'uni_abrev', 'uni_geojson', 'uni_latitud', 'uni_longitud', 'uni_imagen')
                //->whereNull('uni_codsup')
                ->where('uni_estado', 'A')
                ->where('uni_cod', auth()->user()->user_uni_cod)
                ->get();
        }


        return response()->json([
            "unisups" => $unisups,
            "unidades" => $unidades
        ]);
    }

    /*public function mapadivision()
    {
        $unisups = Unidade::select('uni_cod','uni_abrev','uni_geojson','uni_latitud','uni_longitud','uni_imagen')
                           ->whereNull('uni_codsup')
                           ->where('uni_cod',auth()->user()->user_uni_cod)
                           ->where('uni_estado','A')
                           ->get();

        $unidades = Unidade::select('uni_cod','uni_abrev','uni_latitud','uni_longitud','uni_codsup','uni_imagen')
                           ->where('uni_estado','A')
                           ->where('uni_codsup',auth()->user()->user_uni_cod)
                           ->get();
        return response()->json([
            "unisups" => $unisups,
            "unidades" => $unidades
        ]);
    }*/
    public function mapadivision(Request $request)
    {
        // Obtener el código de la unidad padre desde la petición
        $codigoPadre = $request->codigo_padre;

        // Si no hay código padre, devolver todas las unidades superiores (sin padre)
        if (empty($codigoPadre) || $codigoPadre == 'null' || $codigoPadre == 'undefined') {
            // Obtener todas las unidades que son padres (sin uni_codsup)
            $unisups = Unidade::select('uni_cod', 'uni_abrev', 'uni_geojson', 'uni_latitud', 'uni_longitud', 'uni_imagen')
                ->whereNull('uni_codsup')
                ->where('uni_estado', 'A')
                ->get();

            // No hay unidades hijas porque no hay padre seleccionado
            $unidades = collect();

            return response()->json([
                "success" => true,
                "unisups" => $unisups,
                "unidades" => $unidades,
                "codigo_padre" => null
            ]);
        }

        // Validar que sea numérico
        if (!is_numeric($codigoPadre)) {
            return response()->json([
                "success" => false,
                "message" => "El código de unidad debe ser numérico",
                "unisups" => [],
                "unidades" => []
            ], 400);
        }

        $codigoPadre = (int)$codigoPadre;

        // Obtener la unidad superior (la que se seleccionó como padre)
        $unisups = Unidade::select('uni_cod', 'uni_abrev', 'uni_geojson', 'uni_latitud', 'uni_longitud', 'uni_imagen')
            ->where('uni_cod', $codigoPadre)
            ->where('uni_estado', 'A')
            ->get();

        // Obtener las unidades hijas de la unidad padre seleccionada
        $unidades = Unidade::select('uni_cod', 'uni_abrev', 'uni_latitud', 'uni_longitud', 'uni_codsup', 'uni_imagen')
            ->where('uni_estado', 'A')
            ->where('uni_codsup', $codigoPadre)
            ->get();

        return response()->json([
            "success" => true,
            "unisups" => $unisups,
            "unidades" => $unidades,
            "codigo_padre" => $codigoPadre
        ]);
    }

    /*public function markers(Request $request)
    {
        $fecha = $request->fecha ?? now()->toDateString();

        $markes = UserMonitoreo::select(
                'umoni_uni_cod',
                'umoni_latitud',
                'umoni_longitud',
                'umoni_fechahora',
                DB::raw("CONCAT(grados.grad_abrev,' ',especialidades.espe_abrev,' ',personas.per_nombres,' ',personas.per_apaterno,' ',personas.per_amaterno) AS pesonal")
            )
            ->join('unidades','unidades.uni_cod','=','user_monitoreos.umoni_uni_cod')
            ->join('users','users.id','=','user_monitoreos.umoni_user_id')
            ->join('personas','personas.per_cod','=','users.user_per_cod')
            ->leftJoin('persona_grados AS pg', function($join){
                $join->on('pg.pergrad_per_cod','=','personas.per_cod')
                ->where('pg.pergrad_estado','=','A');
            })
            ->leftJoin('grados','grados.grad_cod','=','pg.pergrad_grad_cod')
            ->leftJoin('persona_especialidades AS pe', function($join){
                $join->on('pe.perespe_per_cod','=','personas.per_cod')
                ->where('pe.perespe_estado','=','A');
            })
            ->leftJoin('especialidades','especialidades.espe_cod','=','pe.perespe_espe_cod')
            ->whereDate('umoni_fechahora', $fecha)
            ->where('unidades.uni_codsup',auth()->user()->user_uni_cod)
            ->where('umoni_estado', 'A')
            ->orderBy('umoni_uni_cod')
            ->orderBy('umoni_fechahora')
            ->get();

        return response()->json([
            "markes" => $markes
        ]);
    }*/

    public function markers(Request $request)
    {
        $fecha = $request->fecha ?? now()->toDateString();
        $unidad = $request->unidad; // Nuevo parámetro

        $query = UserMonitoreo::select(
            'umoni_uni_cod',
            'umoni_latitud',
            'umoni_longitud',
            'umoni_fechahora',
            DB::raw("CONCAT(grados.grad_abrev,' ',especialidades.espe_abrev,' ',personas.per_nombres,' ',personas.per_apaterno,' ',personas.per_amaterno) AS pesonal")
        )
            ->join('unidades', 'unidades.uni_cod', '=', 'user_monitoreos.umoni_uni_cod')
            ->join('users', 'users.id', '=', 'user_monitoreos.umoni_user_id')
            ->join('personas', 'personas.per_cod', '=', 'users.user_per_cod')
            ->leftJoin('persona_grados AS pg', function ($join) {
                $join->on('pg.pergrad_per_cod', '=', 'personas.per_cod')
                    ->where('pg.pergrad_estado', '=', 'A');
            })
            ->leftJoin('grados', 'grados.grad_cod', '=', 'pg.pergrad_grad_cod')
            ->leftJoin('persona_especialidades AS pe', function ($join) {
                $join->on('pe.perespe_per_cod', '=', 'personas.per_cod')
                    ->where('pe.perespe_estado', '=', 'A');
            })
            ->leftJoin('especialidades', 'especialidades.espe_cod', '=', 'pe.perespe_espe_cod')
            ->whereDate('umoni_fechahora', $fecha)
            //->where('unidades.uni_codsup', auth()->user()->user_uni_cod)
            ->where('umoni_estado', 'A');

        // Aplicar filtro de unidad si se proporciona
        if ($unidad) {
            $query->where('umoni_uni_cod', $unidad);
        }

        $markes = $query->orderBy('umoni_uni_cod')
            ->orderBy('umoni_fechahora')
            ->get();

        return response()->json([
            "markes" => $markes
        ]);
    }

    public function markersunidad(Request $request)
    {
        $fecha = $request->fecha ?? now()->toDateString();

        $markes = UserMonitoreo::select(
            'umoni_uni_cod',
            'umoni_latitud',
            'umoni_longitud',
            'umoni_fechahora',
            DB::raw("CONCAT(grados.grad_abrev,' ',especialidades.espe_abrev,' ',personas.per_nombres,' ',personas.per_apaterno,' ',personas.per_amaterno) AS pesonal")
        )
            ->join('users', 'users.id', '=', 'user_monitoreos.umoni_user_id')
            ->join('personas', 'personas.per_cod', '=', 'users.user_per_cod')
            ->leftJoin('persona_grados AS pg', function ($join) {
                $join->on('pg.pergrad_per_cod', '=', 'personas.per_cod')
                    ->where('pg.pergrad_estado', '=', 'A');
            })
            ->leftJoin('grados', 'grados.grad_cod', '=', 'pg.pergrad_grad_cod')
            ->leftJoin('persona_especialidades AS pe', function ($join) {
                $join->on('pe.perespe_per_cod', '=', 'personas.per_cod')
                    ->where('pe.perespe_estado', '=', 'A');
            })
            ->leftJoin('especialidades', 'especialidades.espe_cod', '=', 'pe.perespe_espe_cod')
            ->whereDate('umoni_fechahora', $fecha)
            ->where('umoni_uni_cod', auth()->user()->user_uni_cod)
            ->where('umoni_estado', 'A')
            ->orderBy('umoni_uni_cod')
            ->orderBy('umoni_fechahora')
            ->get();

        return response()->json([
            "markes" => $markes
        ]);
    }

    /*************************/
    public function getUnidadesPadre(Request $request)
    {
        $search = $request->search ?? '';
        if (auth()->user()->roles[0]->name == 'G-3') {
            $query = Unidade::select("uni_cod", "uni_detalle", "uni_abrev")
                ->where('uni_estado', 'A')
                ->where('uni_cod', auth()->user()->user_uni_cod);
        } else {
            $query = Unidade::select("uni_cod", "uni_detalle", "uni_abrev")
                ->where('uni_estado', 'A')
                ->where(function ($q) {
                    $q->whereNull('uni_codsup')
                        ->orWhere('uni_codsup', 0);
                });
        }

        if ($search) {
            $query->where('uni_detalle', 'ilike', "%{$search}%");
        }

        $unidades = $query->orderBy('uni_detalle')->get();

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

    /**
     * Obtener unidades hijas de una unidad padre específica
     */
    public function getUnidadesHijas(Request $request)
    {
        $codigoPadre = $request->codigo_padre;
        $search = $request->search ?? '';

        if (!$codigoPadre) {
            return response()->json([
                "success" => false,
                "message" => "Se requiere el código de la unidad padre",
                "data" => []
            ]);
        }

        // Validar que el código padre sea numérico
        if (!is_numeric($codigoPadre)) {
            return response()->json([
                "success" => false,
                "message" => "El código de la unidad padre debe ser numérico",
                "data" => []
            ]);
        }

        $query = Unidade::select("uni_cod", "uni_detalle", "uni_abrev", "uni_codsup")
            ->where('uni_estado', 'A')
            ->where('uni_codsup', (int)$codigoPadre);

        if ($search) {
            $query->where('uni_detalle', 'ilike', "%{$search}%");
        }

        $unidades = $query->orderBy('uni_detalle')->get();

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

    /**
     * Obtener una unidad específica con sus datos completos
     */
    public function getUnidadById($codigo)
    {
        // Validar que el código sea numérico
        if (!is_numeric($codigo)) {
            return response()->json([
                "success" => false,
                "message" => "El código de la unidad debe ser numérico"
            ], 400);
        }

        $unidad = Unidade::select(
            "uni_cod",
            "uni_detalle",
            "uni_abrev",
            "uni_codsup",
            "uni_latitud",
            "uni_longitud",
            "uni_imagen"
        )->where('uni_cod', (int)$codigo)
            ->where('uni_estado', 'A')
            ->first();

        if (!$unidad) {
            return response()->json([
                "success" => false,
                "message" => "Unidad no encontrada"
            ], 404);
        }

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

    public function divisiones()
    {
        $divisiones = Unidade::select('uni_cod', 'uni_detalle', 'uni_abrev')
            ->where('uni_estado', 'A')
            ->whereNull('uni_codsup')
            ->orderBy('uni_abrev', 'asc')->get();
        return response()->json([
            "success" => true,
            "divisiones" => $divisiones
        ]);
    }

    public function unidependientes($uni_cod)
    {
        $unidependientes = Unidade::select('uni_cod', 'uni_detalle', 'uni_abrev')
            ->where('uni_estado', 'A')
            ->where('uni_codsup', $uni_cod)
            ->orderBy('uni_abrev', 'asc')->get();
        return response()->json([
            "success" => true,
            "unidependientes" => $unidependientes
        ]);
    }

    /*PUESTOS DE ACADA UNIDAD*/
    public function listpuestos(Request $request, $id)
    {
        $search = $request->get("search");

        $puestos = Puesto::select(
            'puesto_cod',
            'puesto_detalle',
            'puesto_tipo',
            'puesto_geojson'
        )
            ->where(DB::raw("puesto_detalle"), 'ilike', "%{$search}%")
            ->where("puesto_estado", "A")
            ->where("puesto_uni_cod", $id)
            ->orderBy("puesto_cod", "desc")
            ->get();

        return response()->json([
            "puestos" => $puestos
        ]);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function storepuesto(Request $request)
    {
        $tiposPermitidos = [
            'PP.MM.',
            'PP.MM.AA.',
            'PP.SS.',
        ];

        if (
            !$request->puesto_tipo ||
            !in_array($request->puesto_tipo, $tiposPermitidos, true)
        ) {
            return response()->json([
                "message" => 422,
                "message_text" => "SELECCIONE UN TIPO DE PUESTO VÁLIDO"
            ], 422);
        }

        $is_puesto_exists = Puesto::where("puesto_detalle", $request->puesto_detalle)->first();

        if ($is_puesto_exists) {
            return response()->json([
                "message" => 403,
                "message_text" => "EL PUESTO YA EXISTE"
            ]);
        }

        $puesto = Puesto::create([
            "puesto_detalle" => $request->puesto_detalle,
            "puesto_tipo" => $request->puesto_tipo,
            "puesto_uni_cod" => $request->puesto_uni_cod,
            "puesto_geojson" => $request->puesto_geojson,
            "puesto_estado" => "A",
            "puesto_usuareg" => auth()->user()->id,
            "puesto_fechareg" => Date("Y-m-d")
        ]);

        return response()->json([
            "message" => 200,
            "puesto" => $puesto
        ]);
    }

    /**
     * Display the specified resource.
     */
    public function showpuesto(string $id)
    {
        $puesto = Puesto::where("puesto_cod", $id)
            ->where("puesto_estado", "A")
            ->first();

        if (!$puesto) {
            return response()->json([
                "message" => 404,
                "message_text" => "EL PUESTO NO EXISTE"
            ], 404);
        }

        return response()->json([
            "message" => 200,
            "puesto" => $puesto
        ]);
    }

    /**
     * Update the specified resource in storage.
     */
    public function updatepuesto(Request $request, string $id)
    {
        $tiposPermitidos = [
            'PP.MM.',
            'PP.MM.AA.',
            'PP.SS.',
        ];

        if (
            $request->has('puesto_tipo') &&
            $request->puesto_tipo !== null &&
            !in_array($request->puesto_tipo, $tiposPermitidos, true)
        ) {
            return response()->json([
                "message" => 422,
                "message_text" => "EL TIPO DE PUESTO NO ES VÁLIDO"
            ], 422);
        }

        $is_puesto_exists = Puesto::where("puesto_detalle", $request->puesto_detalle)
            ->where("puesto_cod", "<>", $id)
            ->first();

        if ($is_puesto_exists) {
            return response()->json([
                "message" => 403,
                "message_text" => "EL PUESTO YA EXISTE"
            ]);
        }

        $puesto = Puesto::where("puesto_cod", $id)->first();

        if (!$puesto) {
            return response()->json([
                "message" => 404,
                "message_text" => "EL PUESTO NO EXISTE"
            ], 404);
        }

        $updateData = [
            "puesto_detalle" => $request->puesto_detalle,
            //"puesto_uni_cod" => $request->puesto_uni_cod,
            "puesto_geojson" => $request->puesto_geojson,
            "puesto_usuamod" => auth()->user()->id,
            "puesto_fechamod" => Date("Y-m-d")
        ];

        /*
         * Los puestos antiguos pueden tener puesto_tipo = NULL.
         * Solo se actualiza el tipo cuando el Frontend lo envía.
         */
        if ($request->has('puesto_tipo')) {
            $updateData["puesto_tipo"] = $request->puesto_tipo;
        }

        $puesto->update($updateData);

        return response()->json([
            "message" => 200,
            "puesto" => $puesto
        ]);
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroypuesto(string $id)
    {
        $puesto = Puesto::where("puesto_cod", $id)->first();
        $puesto->puesto_estado = "N";
        $puesto->puesto_fechabaja = Date("Y-m-d");
        $puesto->puesto_usuabaja = auth()->user()->id;
        $puesto->save();

        return response()->json([
            "message" => 200
        ]);
    }

    /*PUESTO POR UNIDAD*/
    public function getpuestosunidad($uni_cod)
    {
        $puestos = Puesto::select(
            'puesto_cod',
            'puesto_detalle',
            'puesto_tipo'
        )
            ->where('puesto_uni_cod', $uni_cod)
            ->where('puesto_estado', 'A')
            ->get();

        return response()->json([
            "message" => 200,
            "puestos" => $puestos
        ]);
    }

    /*MISIONES POR PUESTOS*/
    public function getmisionespuestos($puesto_cod)
    {
        $misones = Misione::select(
            'mision_cod',
            'mision_descrip',
            'mision_fecha',
            'mision_fechafin',
            DB::raw("(
                                                SELECT COUNT(DISTINCT misione_items.mitem_user_id)
                                                FROM misione_items
                                                WHERE misione_items.mitem_mision_cod = misiones.mision_cod
                                                AND misione_items.mitem_estado = 'A'
                                            ) as total_asignados")
        )
            ->where('mision_puesto_cod', $puesto_cod)
            ->where('mision_estado', 'A')
            ->get();

        return response()->json([
            "message" => 200,
            "misones" => $misones
        ]);
    }

    public function getpersonalmision($mision_cod)
    {
        $personal = MisioneItem::select(
            "misione_items.mitem_cod",
            "misiones.mision_fecha",
            "misiones.mision_uni_cod",
            DB::raw("CONCAT(grados.grad_abrev,' ',especialidades.espe_abrev,' ',personas.per_nombres,' ',personas.per_apaterno,' ',personas.per_amaterno) AS persona")
        )
            ->join("misiones", "misiones.mision_cod", "=", "misione_items.mitem_mision_cod")
            ->join("users", "users.id", "=", "misione_items.mitem_user_id")
            ->join("personas", "personas.per_cod", "=", "users.user_per_cod")
            ->leftJoin('persona_grados AS pg', function ($join) {
                $join->on('pg.pergrad_per_cod', '=', 'personas.per_cod')
                    ->where('pg.pergrad_estado', '=', 'A');
            })
            ->leftJoin('grados', 'grados.grad_cod', '=', 'pg.pergrad_grad_cod')
            ->leftJoin('persona_especialidades AS pe', function ($join) {
                $join->on('pe.perespe_per_cod', '=', 'personas.per_cod')
                    ->where('pe.perespe_estado', '=', 'A');
            })
            ->leftJoin('especialidades', 'especialidades.espe_cod', '=', 'pe.perespe_espe_cod')
            ->leftJoin('armas', 'armas.arma_cod', '=', 'personas.per_arma_cod')
            ->where("misione_items.mitem_mision_cod", $mision_cod)
            ->where("misione_items.mitem_estado", "A")
            ->orderBy("misione_items.mitem_cod", "desc")->get();

        return response()->json([
            "message" => 200,
            "personal" => $personal
        ]);
    }

    /*public function getMarkersPorMision($mision_cod)
    {
        $fecha = request()->input('fecha');

        $markers = UserMonitoreo::select(
                'user_monitoreos.umoni_cod',
                'user_monitoreos.umoni_uni_cod',
                'user_monitoreos.umoni_latitud',
                'user_monitoreos.umoni_longitud',
                'user_monitoreos.umoni_fechahora',
                DB::raw("CONCAT(grados.grad_abrev,' ',especialidades.espe_abrev,' ',personas.per_nombres,' ',personas.per_apaterno,' ',personas.per_amaterno) AS personal"),
                DB::raw("(SELECT uni_detalle FROM unidades WHERE uni_cod = user_monitoreos.umoni_uni_cod) AS nombre_unidad")
            )
            ->join('users','users.id','=','user_monitoreos.umoni_user_id')
            ->join('personas','personas.per_cod','=','users.user_per_cod')
            ->leftJoin('persona_grados AS pg', function($join){
                $join->on('pg.pergrad_per_cod','=','personas.per_cod')
                ->where('pg.pergrad_estado','=','A');
            })
            ->leftJoin('grados','grados.grad_cod','=','pg.pergrad_grad_cod')
            ->leftJoin('persona_especialidades AS pe', function($join){
                $join->on('pe.perespe_per_cod','=','personas.per_cod')
                ->where('pe.perespe_estado','=','A');
            })
            ->leftJoin('especialidades','especialidades.espe_cod','=','pe.perespe_espe_cod')
            ->join('misione_items', function($join) use ($mision_cod) {
                $join->on('misione_items.mitem_user_id', '=', 'users.id')
                     ->where('misione_items.mitem_mision_cod', '=', $mision_cod)
                     ->where('misione_items.mitem_estado', '=', 'A');
            })
            ->whereDate('user_monitoreos.umoni_fechahora', $fecha)
            ->where('user_monitoreos.umoni_estado', 'A')
            ->orderBy('user_monitoreos.umoni_uni_cod')
            ->orderBy('user_monitoreos.umoni_fechahora')
            ->get();

        // Obtener total de asignados a la misión
        $totalAsignados = MisioneItem::where('mitem_mision_cod', $mision_cod)
            ->where('mitem_estado', 'A')
            ->count();

        // Obtener detalle de la misión
        $mision = Misione::select('mision_descrip', 'mision_puesto_cod')
            ->where('mision_cod', $mision_cod)
            ->first();

        return response()->json([
            "markers" => $markers,
            "total_asignados" => $totalAsignados,
            "mision_descrip" => $mision ? $mision->mision_descrip : null,
            "mision_puesto_cod" => $mision ? $mision->mision_puesto_cod : null,
            "fecha" => $fecha
        ]);
    }*/

    public function getMarkersPorMision(Request $request, $mision_cod)
    {
        /*
    |--------------------------------------------------------------------------
    | 1. OBTENER DATOS DE LA MISIÓN
    |--------------------------------------------------------------------------
    */
        $mision = Misione::select(
            'mision_cod',
            'mision_descrip',
            'mision_puesto_cod',
            'mision_uni_cod',
            'mision_fecha',
            'mision_fechafin'
        )
            ->where('mision_cod', $mision_cod)
            ->first();

        if (!$mision) {
            return response()->json([
                'message' => 'La misión solicitada no existe.'
            ], 404);
        }


        /*
    |--------------------------------------------------------------------------
    | 2. FILTRO OPCIONAL POR PERSONAL
    |--------------------------------------------------------------------------
    |
    | SIN user_id:
    |   muestra todo el personal como funciona actualmente.
    |
    | CON user_id:
    |   devuelve únicamente el recorrido del personal seleccionado.
    |
    */
        $userIdFiltro = null;

        if ($request->filled('user_id')) {

            $userIdSolicitado = $request->input('user_id');

            if (
                !is_numeric($userIdSolicitado)
                || (int) $userIdSolicitado <= 0
            ) {
                return response()->json([
                    'message' =>
                    'El identificador del personal seleccionado no es válido.'
                ], 422);
            }

            $userIdFiltro = (int) $userIdSolicitado;
        }


        /*
    |--------------------------------------------------------------------------
    | 3. VALIDAR FECHA
    |--------------------------------------------------------------------------
    */
        try {

            $fechaInicio = $mision->mision_fecha
                ? Carbon::parse($mision->mision_fecha)->startOfDay()
                : null;

            $fechaFin = $mision->mision_fechafin
                ? Carbon::parse($mision->mision_fechafin)->endOfDay()
                : Carbon::today()->endOfDay();


            if (
                $fechaInicio
                && $fechaFin->lt($fechaInicio)
            ) {
                $fechaFin =
                    $fechaInicio
                    ->copy()
                    ->endOfDay();
            }


            if ($request->filled('fecha')) {

                $fechaSolicitada =
                    $request->input('fecha');

                if (
                    !is_string($fechaSolicitada)
                    || !preg_match(
                        '/^\d{4}-\d{2}-\d{2}$/',
                        $fechaSolicitada
                    )
                ) {
                    throw new \InvalidArgumentException(
                        'Formato de fecha inválido.'
                    );
                }


                [
                    $anio,
                    $mes,
                    $dia
                ] = array_map(
                    'intval',
                    explode(
                        '-',
                        $fechaSolicitada
                    )
                );


                $fechaSeleccionada =
                    Carbon::createSafe(
                        $anio,
                        $mes,
                        $dia
                    )
                    ->startOfDay();
            } else {

                $fechaSeleccionada =
                    $fechaInicio
                    ? $fechaInicio->copy()
                    : Carbon::today()->startOfDay();
            }
        } catch (\Throwable $error) {

            return response()->json([
                'message' =>
                'La fecha enviada no tiene el formato válido YYYY-MM-DD.'
            ], 422);
        }


        if (
            $fechaInicio
            && $fechaSeleccionada->lt($fechaInicio)
        ) {
            return response()->json([
                'message' =>
                'La fecha seleccionada es anterior al inicio de la misión.',

                'fecha_minima' =>
                $fechaInicio->toDateString(),

                'fecha_maxima' =>
                $fechaFin->toDateString(),
            ], 422);
        }


        if (
            $fechaSeleccionada->gt($fechaFin)
        ) {
            return response()->json([
                'message' =>
                'La fecha seleccionada está fuera del periodo de la misión.',

                'fecha_minima' =>
                $fechaInicio?->toDateString(),

                'fecha_maxima' =>
                $fechaFin->toDateString(),
            ], 422);
        }


        $fecha =
            $fechaSeleccionada->toDateString();


        /*
    |--------------------------------------------------------------------------
    | 4. OBTENER TODO EL PERSONAL ASIGNADO
    |--------------------------------------------------------------------------
    |
    | Esta lista NO se filtra porque será utilizada para llenar el selector
    | del Frontend.
    |
    */
        $usuariosMisionTodos =
            MisioneItem::select(

                'misione_items.mitem_user_id',

                'personas.per_cod',

                DB::raw("
                TRIM(
                    CONCAT(
                        COALESCE(grados.grad_abrev, ''),
                        ' ',
                        COALESCE(especialidades.espe_abrev, ''),
                        ' ',
                        COALESCE(personas.per_nombres, ''),
                        ' ',
                        COALESCE(personas.per_apaterno, ''),
                        ' ',
                        COALESCE(personas.per_amaterno, '')
                    )
                ) AS personal_nombre
            ")
            )

            ->join(
                'users',
                'users.id',
                '=',
                'misione_items.mitem_user_id'
            )

            ->join(
                'personas',
                'personas.per_cod',
                '=',
                'users.user_per_cod'
            )

            ->leftJoin(
                'persona_grados AS pg',
                function ($join) {

                    $join->on(
                        'pg.pergrad_per_cod',
                        '=',
                        'personas.per_cod'
                    )

                        ->where(
                            'pg.pergrad_estado',
                            '=',
                            'A'
                        );
                }
            )

            ->leftJoin(
                'grados',
                'grados.grad_cod',
                '=',
                'pg.pergrad_grad_cod'
            )

            ->leftJoin(
                'persona_especialidades AS pe',
                function ($join) {

                    $join->on(
                        'pe.perespe_per_cod',
                        '=',
                        'personas.per_cod'
                    )

                        ->where(
                            'pe.perespe_estado',
                            '=',
                            'A'
                        );
                }
            )

            ->leftJoin(
                'especialidades',
                'especialidades.espe_cod',
                '=',
                'pe.perespe_espe_cod'
            )

            ->where(
                'misione_items.mitem_mision_cod',
                $mision_cod
            )

            ->where(
                'misione_items.mitem_estado',
                'A'
            )

            ->get()

            ->unique(
                'mitem_user_id'
            )

            ->values();


        /*
    |--------------------------------------------------------------------------
    | 5. VALIDAR PERSONAL SELECCIONADO
    |--------------------------------------------------------------------------
    */
        if ($userIdFiltro !== null) {

            $personalExisteEnMision =
                $usuariosMisionTodos->contains(
                    function ($usuario) use ($userIdFiltro) {

                        return
                            (int) $usuario->mitem_user_id
                            ===
                            $userIdFiltro;
                    }
                );


            if (!$personalExisteEnMision) {

                return response()->json([
                    'message' =>
                    'El personal seleccionado no se encuentra asignado a esta operación.'
                ], 422);
            }
        }


        /*
    |--------------------------------------------------------------------------
    | 6. LISTA DEL PERSONAL PARA EL SELECTOR
    |--------------------------------------------------------------------------
    */
        $personalAsignado =
            $usuariosMisionTodos
            ->map(
                function ($usuario) {

                    return [

                        'user_id' =>
                        (int) $usuario->mitem_user_id,

                        'per_cod' =>
                        (int) $usuario->per_cod,

                        'persona' =>
                        trim(
                            $usuario->personal_nombre
                        ),
                    ];
                }
            )

            ->values();


        /*
    |--------------------------------------------------------------------------
    | 7. PERSONAL QUE SE MOSTRARÁ EN EL MAPA
    |--------------------------------------------------------------------------
    */
        if ($userIdFiltro !== null) {

            $usuariosMision =
                $usuariosMisionTodos

                ->filter(
                    function ($usuario) use ($userIdFiltro) {

                        return
                            (int) $usuario->mitem_user_id
                            ===
                            $userIdFiltro;
                    }
                )

                ->values()

                ->keyBy(
                    'mitem_user_id'
                );
        } else {

            $usuariosMision =
                $usuariosMisionTodos
                ->keyBy(
                    'mitem_user_id'
                );
        }


        /*
    |--------------------------------------------------------------------------
    | 8. OBTENER MONITOREO GPS
    |--------------------------------------------------------------------------
    */
        $monitoreos =
            UserMonitoreo::select(

                'user_monitoreos.*',

                DB::raw("
                (
                    SELECT uni_detalle
                    FROM unidades
                    WHERE uni_cod = user_monitoreos.umoni_uni_cod
                ) AS nombre_unidad
            "),

                DB::raw("
                (
                    SELECT uni_abrev
                    FROM unidades
                    WHERE uni_cod = user_monitoreos.umoni_uni_cod
                ) AS abrev_unidad
            ")
            )

            ->whereIn(
                'user_monitoreos.umoni_user_id',
                $usuariosMision
                    ->keys()
                    ->toArray()
            )

            ->whereDate(
                'user_monitoreos.umoni_fechahora',
                $fecha
            )

            ->where(
                'user_monitoreos.umoni_estado',
                'A'
            )

            ->orderBy(
                'user_monitoreos.umoni_fechahora'
            )

            ->get()

            ->groupBy(
                'umoni_user_id'
            );


        /*
    |--------------------------------------------------------------------------
    | 9. CONSTRUIR MARCADORES
    |--------------------------------------------------------------------------
    */
        $markers = [];


        foreach (
            $usuariosMision
            as $userId => $usuario
        ) {

            $monitoreosUser =
                $monitoreos->get(
                    $userId,
                    collect()
                );


            /*
        |--------------------------------------------------------------------------
        | PERSONAL SIN POSICIONES
        |--------------------------------------------------------------------------
        */
            if ($monitoreosUser->isEmpty()) {

                $markers[] =
                    (object) [

                        'umoni_cod' =>
                        null,

                        'umoni_user_id' =>
                        (int) $userId,

                        'umoni_uni_cod' =>
                        null,

                        'umoni_latitud' =>
                        null,

                        'umoni_longitud' =>
                        null,

                        'umoni_fechahora' =>
                        $fecha,

                        'personal' =>
                        trim(
                            $usuario->personal_nombre
                        ),

                        'nombre_unidad' =>
                        'Sin ubicación',

                        'abrev_unidad' =>
                        'N/A',

                        'tiene_monitoreo' =>
                        false,
                    ];
            } else {

                /*
            |--------------------------------------------------------------------------
            | PERSONAL CON POSICIONES
            |--------------------------------------------------------------------------
            */
                foreach (
                    $monitoreosUser
                    as $monitoreo
                ) {

                    $markers[] =
                        (object) [

                            'umoni_cod' =>
                            $monitoreo->umoni_cod,

                            'umoni_user_id' =>
                            (int) $userId,

                            'umoni_uni_cod' =>
                            $monitoreo->umoni_uni_cod,

                            'umoni_latitud' =>
                            $monitoreo->umoni_latitud,

                            'umoni_longitud' =>
                            $monitoreo->umoni_longitud,

                            'umoni_fechahora' =>
                            $monitoreo->umoni_fechahora,

                            'personal' =>
                            trim(
                                $usuario->personal_nombre
                            ),

                            'nombre_unidad' =>
                            $monitoreo->nombre_unidad
                                ??
                                'Unidad desconocida',

                            'abrev_unidad' =>
                            $monitoreo->abrev_unidad
                                ??
                                'N/A',

                            'tiene_monitoreo' =>
                            true,
                        ];
                }
            }
        }


        /*
    |--------------------------------------------------------------------------
    | 10. DATOS DE LA UNIDAD
    |--------------------------------------------------------------------------
    */
        $unidadInfo = null;
        $divisionInfo = null;


        if ($mision->mision_uni_cod) {

            $unidadInfo =
                Unidade::select(
                    'uni_cod',
                    'uni_detalle',
                    'uni_abrev',
                    'uni_codsup'
                )

                ->where(
                    'uni_cod',
                    $mision->mision_uni_cod
                )

                ->first();


            /*
        |--------------------------------------------------------------------------
        | DIVISIÓN SUPERIOR
        |--------------------------------------------------------------------------
        */
            if ($unidadInfo) {

                if ($unidadInfo->uni_codsup) {

                    $divisionInfo =
                        Unidade::select(
                            'uni_cod',
                            'uni_detalle',
                            'uni_abrev'
                        )

                        ->where(
                            'uni_cod',
                            $unidadInfo->uni_codsup
                        )

                        ->first();
                } else {

                    /*
                 * Si la misión estuviera asignada directamente a una División.
                 */
                    $divisionInfo =
                        (object) [

                            'uni_cod' =>
                            $unidadInfo->uni_cod,

                            'uni_detalle' =>
                            $unidadInfo->uni_detalle,

                            'uni_abrev' =>
                            $unidadInfo->uni_abrev,
                        ];
                }
            }
        }


        /*
    |--------------------------------------------------------------------------
    | 11. DATOS DEL PUESTO
    |--------------------------------------------------------------------------
    */
        $puestoInfo = null;


        if ($mision->mision_puesto_cod) {

            $puestoInfo =
                Puesto::select(
                    'puesto_cod',
                    'puesto_detalle',
                    'puesto_tipo'
                )

                ->where(
                    'puesto_cod',
                    $mision->mision_puesto_cod
                )

                ->first();
        }


        /*
    |--------------------------------------------------------------------------
    | 12. PERSONAL SELECCIONADO
    |--------------------------------------------------------------------------
    */
        $personalSeleccionado = null;


        if ($userIdFiltro !== null) {

            $personalSeleccionado =
                $personalAsignado->first(
                    function ($usuario) use ($userIdFiltro) {

                        return
                            (int) $usuario['user_id']
                            ===
                            $userIdFiltro;
                    }
                );
        }


        /*
    |--------------------------------------------------------------------------
    | 13. RESPUESTA
    |--------------------------------------------------------------------------
    */
        return response()->json([

            'message' => 200,


            /*
        |--------------------------------------------------------------------------
        | MARCADORES
        |--------------------------------------------------------------------------
        */
            'markers' =>
            $markers,


            /*
        |--------------------------------------------------------------------------
        | PERSONAL PARA EL SELECTOR
        |--------------------------------------------------------------------------
        */
            'personal_asignado' =>
            $personalAsignado,


            /*
        |--------------------------------------------------------------------------
        | FILTRO
        |--------------------------------------------------------------------------
        */
            'user_id_filtrado' =>
            $userIdFiltro,

            'filtro_personal_activo' =>
            $userIdFiltro !== null,

            'personal_seleccionado' =>
            $personalSeleccionado,


            /*
        |--------------------------------------------------------------------------
        | TOTALES
        |--------------------------------------------------------------------------
        */
            'total_asignados' =>
            $usuariosMisionTodos->count(),

            'total_filtrados' =>
            $usuariosMision->count(),

            'total_con_monitoreo' =>
            $monitoreos->count(),


            /*
        |--------------------------------------------------------------------------
        | MISIÓN
        |--------------------------------------------------------------------------
        */
            'mision_cod' =>
            (int) $mision_cod,

            'mision_descrip' =>
            $mision->mision_descrip,

            'mision_uni_cod' =>
            $mision->mision_uni_cod,

            'mision_puesto_cod' =>
            $mision->mision_puesto_cod,

            'mision_fecha' =>
            $mision->mision_fecha,

            'mision_fechafin' =>
            $mision->mision_fechafin,


            /*
        |--------------------------------------------------------------------------
        | PUESTO
        |--------------------------------------------------------------------------
        */
            'puesto_detalle' =>
            $puestoInfo
                ? $puestoInfo->puesto_detalle
                : null,

            'puesto_tipo' =>
            $puestoInfo
                ? $puestoInfo->puesto_tipo
                : null,


            /*
        |--------------------------------------------------------------------------
        | UNIDAD
        |--------------------------------------------------------------------------
        */
            'unidad' =>
            $unidadInfo
                ? [
                    'uni_cod' =>
                    (int) $unidadInfo->uni_cod,

                    'uni_detalle' =>
                    $unidadInfo->uni_detalle,

                    'uni_abrev' =>
                    $unidadInfo->uni_abrev,
                ]
                : null,

            'unidad_cod' =>
            $unidadInfo
                ? (int) $unidadInfo->uni_cod
                : null,

            'unidad_detalle' =>
            $unidadInfo
                ? $unidadInfo->uni_detalle
                : null,

            'unidad_abrev' =>
            $unidadInfo
                ? $unidadInfo->uni_abrev
                : null,


            /*
        |--------------------------------------------------------------------------
        | DIVISIÓN
        |--------------------------------------------------------------------------
        */
            'division' =>
            $divisionInfo
                ? [
                    'uni_cod' =>
                    (int) $divisionInfo->uni_cod,

                    'uni_detalle' =>
                    $divisionInfo->uni_detalle,

                    'uni_abrev' =>
                    $divisionInfo->uni_abrev,
                ]
                : null,

            'division_cod' =>
            $divisionInfo
                ? (int) $divisionInfo->uni_cod
                : null,

            'division_detalle' =>
            $divisionInfo
                ? $divisionInfo->uni_detalle
                : null,

            'division_abrev' =>
            $divisionInfo
                ? $divisionInfo->uni_abrev
                : null,


            /*
        |--------------------------------------------------------------------------
        | FECHAS
        |--------------------------------------------------------------------------
        */
            'fecha_minima' =>
            $fechaInicio?->toDateString(),

            'fecha_maxima' =>
            $fechaFin->toDateString(),

            'fecha' =>
            $fecha,
        ]);
    }

    public function puestogeojson($puesto_cod)
    {
        $puesto = Puesto::select('puesto_cod', 'puesto_geojson')->where('puesto_cod', $puesto_cod)->first();

        return response()->json([
            "puesto" => $puesto
        ]);
    }

    public function dashboard()
    {
        $user = auth()->user();
        $roleName = $user->getRoleNames()->first();
        $isGlobal = in_array($roleName, ['Administrador', 'Super-Admin', 'Admin-Dpto-III'], true);

        if ($isGlobal) {
            $unidadesIds = null;
        } elseif ($roleName === 'G-3') {
            $unidadesIds = Unidade::where('uni_estado', 'A')
                ->where('uni_codsup', $user->user_uni_cod)
                ->pluck('uni_cod');
        } elseif (in_array($roleName, ['P-3', 'Personal'], true)) {
            $unidadesIds = collect([$user->user_uni_cod])->filter();
        } else {
            return response()->json([
                'message' => 'El rol no tiene acceso al panel operativo.',
            ], 403);
        }

        $unidadesQuery = Unidade::where('uni_estado', 'A');
        $misionesQuery = Misione::where('mision_estado', 'A');
        $personalQuery = Persona::where('personas.per_estado', 'A');

        if ($unidadesIds !== null) {
            $unidadesQuery->whereIn('uni_cod', $unidadesIds);
            $misionesQuery->whereIn('mision_uni_cod', $unidadesIds);
            $personalQuery
                ->join('destino_persona_unidades as dpu', 'dpu.dpuni_per_cod', '=', 'personas.per_cod')
                ->where('dpu.dpuni_estado', 'A')
                ->whereIn('dpu.dpuni_uni_cod', $unidadesIds);
        }

        $startOfDay = now()->startOfDay();
        $endOfDay = $startOfDay->copy()->addDay();
        $positionsQuery = UserMonitoreo::query()
            ->join('users', 'users.id', '=', 'user_monitoreos.umoni_user_id')
            ->leftJoin('personas', 'personas.per_cod', '=', 'users.user_per_cod')
            ->leftJoin('persona_grados as pg', function ($join) {
                $join->on('pg.pergrad_per_cod', '=', 'personas.per_cod')
                    ->where('pg.pergrad_estado', '=', 'A');
            })
            ->leftJoin('grados', 'grados.grad_cod', '=', 'pg.pergrad_grad_cod')
            ->leftJoin('persona_especialidades as pe', function ($join) {
                $join->on('pe.perespe_per_cod', '=', 'personas.per_cod')
                    ->where('pe.perespe_estado', '=', 'A');
            })
            ->leftJoin('especialidades', 'especialidades.espe_cod', '=', 'pe.perespe_espe_cod')
            ->leftJoin('unidades', 'unidades.uni_cod', '=', 'user_monitoreos.umoni_uni_cod')
            ->where('user_monitoreos.umoni_estado', 'A')
            ->where('user_monitoreos.umoni_fechahora', '>=', $startOfDay)
            ->where('user_monitoreos.umoni_fechahora', '<', $endOfDay);

        if ($unidadesIds !== null) {
            $positionsQuery->whereIn('user_monitoreos.umoni_uni_cod', $unidadesIds);
        }

        $posicionesreportadas = (clone $positionsQuery)->count('user_monitoreos.umoni_cod');
        $lastPositions = $positionsQuery
            ->select(
                'user_monitoreos.umoni_cod',
                'user_monitoreos.umoni_user_id',
                'user_monitoreos.umoni_uni_cod',
                'user_monitoreos.umoni_latitud',
                'user_monitoreos.umoni_longitud',
                'user_monitoreos.umoni_fechahora',
                'unidades.uni_abrev',
                DB::raw("TRIM(CONCAT(COALESCE(grados.grad_abrev, ''), ' ', COALESCE(especialidades.espe_abrev, ''), ' ', COALESCE(personas.per_nombres, ''), ' ', COALESCE(personas.per_apaterno, ''), ' ', COALESCE(personas.per_amaterno, ''))) AS personal")
            )
            ->orderByDesc('user_monitoreos.umoni_fechahora')
            ->limit(50)
            ->get();

        return response()->json([
            'uniactivas' => $unidadesQuery->count(),
            'personalactivo' => $personalQuery->distinct('personas.per_cod')->count('personas.per_cod'),
            'misionesactivas' => $misionesQuery->count(),
            'posicionesreportadas' => $posicionesreportadas,
            'last_positions' => $lastPositions,
        ]);
    }
}
