<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Api\ApiController;
use App\Models\MantProgramacion;
use App\Models\Alerta;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use OpenApi\Attributes as OA;

class ReporteController extends ApiController
{
    /**
     * Dashboard Gerencia
     * GET /api/v1/reportes/dashboard/gerencia
     *
     * Usa el SP: sp_dashboard_gerencia
     */
    #[OA\Get(
        path: "/api/v1/reportes/dashboard/gerencia",
        summary: "Dashboard Gerencia",
        description: "Obtiene KPIs y métricas para el dashboard de gerencia: cumplimiento mensual, por concesión y evolución de últimos 6 meses. Usa el SP sp_dashboard_gerencia",
        tags: ["Reportes"],
        security: [["sanctum" => []]],
        parameters: [
            new OA\Parameter(name: "anio", in: "query", required: false, schema: new OA\Schema(type: "integer", minimum: 2020, maximum: 2030)),
            new OA\Parameter(name: "mes", in: "query", required: false, schema: new OA\Schema(type: "integer", minimum: 1, maximum: 12)),
            new OA\Parameter(name: "concesion_id", in: "query", required: false, schema: new OA\Schema(type: "integer"))
        ],
        responses: [
            new OA\Response(
                response: 200,
                description: "Dashboard de gerencia",
                content: new OA\JsonContent(properties: [
                    new OA\Property(property: "success", type: "boolean", example: true),
                    new OA\Property(property: "data", type: "object", properties: [
                        new OA\Property(property: "periodo", type: "object", properties: [
                            new OA\Property(property: "anio", type: "integer"),
                            new OA\Property(property: "mes", type: "integer"),
                            new OA\Property(property: "nombre_mes", type: "string")
                        ]),
                        new OA\Property(property: "kpis", type: "object", properties: [
                            new OA\Property(property: "total_programados", type: "integer"),
                            new OA\Property(property: "total_completados", type: "integer"),
                            new OA\Property(property: "porcentaje_cumplimiento", type: "number"),
                            new OA\Property(property: "alertas_activas", type: "integer")
                        ]),
                        new OA\Property(property: "por_concesion", type: "array", items: new OA\Items(
                            properties: [
                                new OA\Property(property: "concesion_id", type: "integer"),
                                new OA\Property(property: "nombre", type: "string"),
                                new OA\Property(property: "total", type: "integer"),
                                new OA\Property(property: "completados", type: "integer"),
                                new OA\Property(property: "porcentaje", type: "number")
                            ]
                        )),
                        new OA\Property(property: "evolucion_mensual", type: "array", items: new OA\Items(
                            properties: [
                                new OA\Property(property: "mes", type: "string"),
                                new OA\Property(property: "total", type: "integer"),
                                new OA\Property(property: "completados", type: "integer"),
                                new OA\Property(property: "porcentaje", type: "number")
                            ]
                        ))
                    ])
                ])
            )
        ]
    )]
    public function dashboardGerencia(Request $request): JsonResponse
    {
        return $this->ejecutar(function () use ($request) {

            $request->validate([
                'anio' => 'nullable|integer|min:2020|max:2030',
                'mes' => 'nullable|integer|min:1|max:12',
                'concesion_id' => 'nullable|integer',
            ]);

            $anio = $request->anio ?? now()->year;
            $mes = $request->mes ?? now()->month;

            // Llamar al Stored Procedure
            $resultado = $this->ejecutarSP('sp_dashboard_gerencia', [
                $anio,
                $mes,
                $request->concesion_id,
            ]);

            $respuesta = $this->parsearRespuestaSP($resultado);
            $data = $respuesta['data'] ?? [];

            // Datos adicionales
            $fechaInicio = Carbon::createFromDate($anio, $mes, 1)->startOfMonth();
            $fechaFin = $fechaInicio->copy()->endOfMonth();

            // Por concesión
            $porConcesion = DB::table('mant_programacion as mp')
                ->join('peaje_centro as pc', 'mp.id_centro', '=', 'pc.id_centro')
                ->join('concesiones as c', 'pc.id_concesion', '=', 'c.id_concesion')
                ->join('mant_estados as me', 'mp.estado_id', '=', 'me.estado_id')
                ->whereBetween('mp.fecha_programada', [$fechaInicio, $fechaFin])
                ->where('mp.estado', 1)
                ->select([
                    'c.id_concesion',
                    'c.nombre',
                    DB::raw('COUNT(*) as total'),
                    DB::raw("SUM(CASE WHEN me.estado_codigo IN ('COMPLETADO', 'APROBADO') THEN 1 ELSE 0 END) as completados"),
                ])
                ->groupBy('c.id_concesion', 'c.nombre')
                ->get()
                ->map(fn($c) => [
                    'concesion_id' => $c->id_concesion,
                    'nombre' => $c->nombre,
                    'total' => $c->total,
                    'completados' => $c->completados,
                    'porcentaje' => $c->total > 0 ? round(($c->completados / $c->total) * 100, 1) : 0,
                ]);

            // Evolución mensual (últimos 6 meses)
            $evolucion = [];
            for ($i = 5; $i >= 0; $i--) {
                $fecha = now()->subMonths($i);
                $inicio = $fecha->copy()->startOfMonth();
                $fin = $fecha->copy()->endOfMonth();

                $stats = DB::table('mant_programacion as mp')
                    ->join('mant_estados as me', 'mp.estado_id', '=', 'me.estado_id')
                    ->whereBetween('mp.fecha_programada', [$inicio, $fin])
                    ->where('mp.estado', 1)
                    ->selectRaw("
                        COUNT(*) as total,
                        SUM(CASE WHEN me.estado_codigo IN ('COMPLETADO', 'APROBADO') THEN 1 ELSE 0 END) as completados
                    ")
                    ->first();

                $evolucion[] = [
                    'mes' => $fecha->format('M Y'),
                    'total' => $stats->total ?? 0,
                    'completados' => $stats->completados ?? 0,
                    'porcentaje' => ($stats->total ?? 0) > 0
                        ? round((($stats->completados ?? 0) / $stats->total) * 100, 1)
                        : 0,
                ];
            }

            return $this->successResponse([
                'periodo' => [
                    'anio' => $anio,
                    'mes' => $mes,
                    'nombre_mes' => Carbon::createFromDate($anio, $mes, 1)->monthName,
                ],
                'kpis' => [
                    'total_programados' => $data['total_programados'] ?? 0,
                    'total_completados' => $data['total_completados'] ?? 0,
                    'porcentaje_cumplimiento' => $data['porcentaje'] ?? 0,
                    'alertas_activas' => $data['alertas_activas'] ?? Alerta::activas()->count(),
                ],
                'por_concesion' => $porConcesion,
                'evolucion_mensual' => $evolucion,
            ]);

        }, 'Error obteniendo dashboard gerencia');
    }

    /**
     * Dashboard Admin
     * GET /api/v1/reportes/dashboard/admin
     *
     * Usa el SP: sp_dashboard_admin
     */
    #[OA\Get(
        path: "/api/v1/reportes/dashboard/admin",
        summary: "Dashboard Admin",
        description: "Dashboard operativo para administradores: estado del día, técnicos activos, alertas críticas y QRs próximos a vencer. Usa el SP sp_dashboard_admin",
        tags: ["Reportes"],
        security: [["sanctum" => []]],
        responses: [
            new OA\Response(
                response: 200,
                description: "Dashboard de admin",
                content: new OA\JsonContent(properties: [
                    new OA\Property(property: "success", type: "boolean", example: true),
                    new OA\Property(property: "data", type: "object", properties: [
                        new OA\Property(property: "fecha", type: "string", format: "date"),
                        new OA\Property(property: "hora", type: "string"),
                        new OA\Property(property: "hoy", type: "object", properties: [
                            new OA\Property(property: "programados", type: "integer"),
                            new OA\Property(property: "por_estado", type: "array", items: new OA\Items(type: "object"))
                        ]),
                        new OA\Property(property: "tecnicos_activos", type: "array", items: new OA\Items(type: "object")),
                        new OA\Property(property: "alertas", type: "object", properties: [
                            new OA\Property(property: "total_activas", type: "integer"),
                            new OA\Property(property: "criticas", type: "array", items: new OA\Items(type: "object"))
                        ]),
                        new OA\Property(property: "proximos_vencer_qr", type: "array", items: new OA\Items(type: "object"))
                    ])
                ])
            )
        ]
    )]
    public function dashboardAdmin(): JsonResponse
    {
        return $this->ejecutar(function () {

            // Llamar al Stored Procedure
            $resultado = $this->ejecutarSP('sp_dashboard_admin', []);
            $respuesta = $this->parsearRespuestaSP($resultado);
            $data = $respuesta['data'] ?? [];

            // Datos de hoy con más detalle
            $hoy = DB::table('mant_programacion as mp')
                ->join('mant_estados as me', 'mp.estado_id', '=', 'me.estado_id')
                ->whereDate('mp.fecha_programada', now()->toDateString())
                ->where('mp.estado', 1)
                ->select([
                    'me.estado_codigo',
                    'me.estado_nombre',
                    'me.color_hex',
                    DB::raw('COUNT(*) as total'),
                ])
                ->groupBy('me.estado_codigo', 'me.estado_nombre', 'me.color_hex')
                ->get();

            // Técnicos activos
            $tecnicosActivos = DB::table('mant_programacion as mp')
                ->join('usuarios as u', 'mp.tecnico_asignado', '=', 'u.usu_id')
                ->join('mant_estados as me', 'mp.estado_id', '=', 'me.estado_id')
                ->whereDate('mp.fecha_programada', now()->toDateString())
                ->where('mp.estado', 1)
                ->whereIn('me.estado_codigo', ['CAMINO_PEAJE', 'LLEGADA_PEAJE', 'EN_MANTENIMIENTO'])
                ->select([
                    'u.usu_id',
                    'u.usu_nombre',
                    'u.usu_apellido',
                    'me.estado_nombre',
                    'me.color_hex',
                ])
                ->get()
                ->map(fn($t) => [
                    'id' => $t->usu_id,
                    'nombre' => "{$t->usu_nombre} {$t->usu_apellido}",
                    'estado' => $t->estado_nombre,
                    'color' => $t->color_hex,
                ]);

            // Alertas críticas
            $alertasCriticas = Alerta::criticas()
                ->with(['programacion.centro:id_centro,nombre_centro', 'usuarioAfectado:usu_id,usu_nombre,usu_apellido'])
                ->limit(10)
                ->get()
                ->map(fn($a) => [
                    'alerta_id' => $a->alerta_id,
                    'tipo' => $a->tipo_alerta,
                    'titulo' => $a->titulo,
                    'minutos' => $a->minutos_activa,
                    'peaje' => $a->programacion?->centro?->nombre_centro,
                    'tecnico' => $a->usuarioAfectado?->nombre_completo,
                ]);

            // Próximos a vencer (QR)
            $proximosVencer = MantProgramacion::with(['centro:id_centro,nombre_centro', 'tecnico:usu_id,usu_nombre,usu_apellido'])
                ->whereHas('estadoMantenimiento', fn($q) => $q->where('estado_codigo', 'PEND_APROBACION'))
                ->whereNotNull('qr_expira')
                ->where('qr_expira', '>', now())
                ->where('qr_expira', '<', now()->addHour())
                ->activos()
                ->get()
                ->map(fn($m) => [
                    'prog_id' => $m->prog_id,
                    'peaje' => $m->centro->nombre_centro,
                    'tecnico' => $m->tecnico?->nombre_completo,
                    'minutos_restantes' => now()->diffInMinutes($m->qr_expira, false),
                ]);

            return $this->successResponse([
                'fecha' => now()->toDateString(),
                'hora' => now()->format('H:i'),
                'hoy' => $data['hoy'] ?? [
                    'programados' => $hoy->sum('total'),
                    'por_estado' => $hoy,
                ],
                'tecnicos_activos' => $tecnicosActivos,
                'alertas' => [
                    'total_activas' => $data['alertas_activas'] ?? Alerta::activas()->count(),
                    'criticas' => $alertasCriticas,
                ],
                'proximos_vencer_qr' => $proximosVencer,
            ]);

        }, 'Error obteniendo dashboard admin');
    }

    /**
     * Reporte de mantenimiento individual (datos para PDF)
     * GET /api/v1/reportes/mantenimiento/{progId}/pdf
     *
     * Usa el SP: sp_reporte_mantenimiento
     */
    #[OA\Get(
        path: "/api/v1/reportes/mantenimiento/{progId}/pdf",
        summary: "Datos para reporte PDF de mantenimiento",
        description: "Obtiene todos los datos necesarios para generar el reporte PDF de un mantenimiento: historial, checklist, evidencias, tiempos y aprobación",
        tags: ["Reportes"],
        security: [["sanctum" => []]],
        parameters: [
            new OA\Parameter(name: "progId", in: "path", required: true, schema: new OA\Schema(type: "integer"))
        ],
        responses: [
            new OA\Response(
                response: 200,
                description: "Datos del reporte",
                content: new OA\JsonContent(properties: [
                    new OA\Property(property: "success", type: "boolean", example: true),
                    new OA\Property(property: "data", type: "object", properties: [
                        new OA\Property(property: "reporte", type: "object", properties: [
                            new OA\Property(property: "generado_en", type: "string", format: "date-time"),
                            new OA\Property(property: "generado_por", type: "string")
                        ]),
                        new OA\Property(property: "mantenimiento", type: "object"),
                        new OA\Property(property: "ubicacion", type: "object"),
                        new OA\Property(property: "tecnico", type: "object"),
                        new OA\Property(property: "historial", type: "array", items: new OA\Items(type: "object")),
                        new OA\Property(property: "tiempos", type: "object", properties: [
                            new OA\Property(property: "traslado_minutos", type: "integer"),
                            new OA\Property(property: "espera_minutos", type: "integer"),
                            new OA\Property(property: "ejecucion_minutos", type: "integer"),
                            new OA\Property(property: "aprobacion_minutos", type: "integer"),
                            new OA\Property(property: "total_minutos", type: "integer")
                        ]),
                        new OA\Property(property: "checklist", type: "array", items: new OA\Items(type: "object")),
                        new OA\Property(property: "evidencias", type: "array", items: new OA\Items(type: "object")),
                        new OA\Property(property: "aprobacion", type: "object", nullable: true)
                    ])
                ])
            ),
            new OA\Response(response: 404, description: "Mantenimiento no encontrado")
        ]
    )]
    public function mantenimientoPdf(int $progId): JsonResponse
    {
        return $this->ejecutar(function () use ($progId) {

            $mantenimiento = MantProgramacion::with([
                'estadoMantenimiento',
                'tecnico',
                'centro.concesion',
                'via',
                'historialEstados.estadoAnterior',
                'historialEstados.estadoNuevo',
                'historialEstados.usuarioEjecuta',
                'checklistRespuestas.itemRevision',
                'checklistRespuestas.estadoEquipo',
                'checklistRespuestas.inventario.tipoHardware',
                'checklistRespuestas.inventario.marca',
                'evidencias' => fn($q) => $q->activas(),
                'aprobacion.jefeOperativo',
            ])
            ->where('prog_id', $progId)
            ->first();

            if (!$mantenimiento) {
                return $this->notFoundResponse('Mantenimiento no encontrado');
            }

            // Calcular tiempos
            $tiempos = [];
            $historial = $mantenimiento->historialEstados->sortBy('fecha_cambio');
            $estadosConTiempo = ['CAMINO_PEAJE', 'LLEGADA_PEAJE', 'EN_MANTENIMIENTO', 'PEND_APROBACION'];

            foreach ($historial as $index => $h) {
                if (isset($historial[$index + 1])) {
                    $siguiente = $historial[$index + 1];
                    $tiempos[$h->estadoNuevo->estado_codigo] = $h->fecha_cambio->diffInMinutes($siguiente->fecha_cambio);
                }
            }

            return $this->successResponse([
                'reporte' => [
                    'generado_en' => now()->toIso8601String(),
                    'generado_por' => $this->usuarioActual()?->nombre_completo,
                ],
                'mantenimiento' => [
                    'prog_id' => $mantenimiento->prog_id,
                    'fecha_programada' => $mantenimiento->fecha_programada,
                    'estado' => [
                        'codigo' => $mantenimiento->estadoMantenimiento->estado_codigo,
                        'nombre' => $mantenimiento->estadoMantenimiento->estado_nombre,
                    ],
                ],
                'ubicacion' => [
                    'concesion' => $mantenimiento->centro->concesion->nombre,
                    'peaje' => $mantenimiento->centro->nombre_centro,
                    'via' => $mantenimiento->via?->nombre,
                    'coordenadas' => $mantenimiento->centro->latitud && $mantenimiento->centro->longitud ? [
                        'lat' => $mantenimiento->centro->latitud,
                        'lng' => $mantenimiento->centro->longitud,
                    ] : null,
                ],
                'tecnico' => $mantenimiento->tecnico ? [
                    'nombre' => $mantenimiento->tecnico->nombre_completo,
                    'cedula' => $mantenimiento->tecnico->usu_cedula,
                ] : null,
                'historial' => $historial->map(fn($h) => [
                    'estado' => $h->estadoNuevo->estado_nombre,
                    'fecha' => $h->fecha_cambio,
                    'usuario' => $h->usuarioEjecuta?->nombre_completo,
                    'gps' => $h->tieneGps() ? [
                        'lat' => $h->latitud,
                        'lng' => $h->longitud,
                    ] : null,
                    'observaciones' => $h->observaciones,
                ]),
                'tiempos' => [
                    'traslado_minutos' => $tiempos['CAMINO_PEAJE'] ?? null,
                    'espera_minutos' => $tiempos['LLEGADA_PEAJE'] ?? null,
                    'ejecucion_minutos' => $tiempos['EN_MANTENIMIENTO'] ?? null,
                    'aprobacion_minutos' => $tiempos['PEND_APROBACION'] ?? null,
                    'total_minutos' => array_sum($tiempos),
                ],
                'checklist' => $mantenimiento->checklistRespuestas->groupBy('inventario_id')->map(fn($items, $invId) => [
                    'equipo' => $items->first()->inventario ? [
                        'tipo' => $items->first()->inventario->tipoHardware?->nombre,
                        'marca' => $items->first()->inventario->marca?->nombre,
                        'modelo' => $items->first()->inventario->modelo,
                        'serie' => $items->first()->inventario->serie,
                    ] : null,
                    'items' => $items->map(fn($i) => [
                        'item' => $i->itemRevision->nombre,
                        'estado' => $i->estadoEquipo->nombre,
                        'color' => $i->estadoEquipo->color_hex,
                        'observacion' => $i->observacion,
                    ]),
                ])->values(),
                'evidencias' => $mantenimiento->evidencias->map(fn($e) => [
                    'tipo' => $e->tipo,
                    'nombre' => $e->nombre_archivo,
                    'url' => $e->url,
                    'descripcion' => $e->descripcion,
                    'gps' => $e->tieneGps() ? ['lat' => $e->latitud, 'lng' => $e->longitud] : null,
                ]),
                'aprobacion' => $mantenimiento->aprobacion ? [
                    'tipo' => $mantenimiento->aprobacion->tipo,
                    'fecha' => $mantenimiento->aprobacion->fecha_aprobacion,
                    'jefe' => $mantenimiento->aprobacion->jefeOperativo?->nombre_completo,
                    'observaciones' => $mantenimiento->aprobacion->observaciones,
                    'motivo_rechazo' => $mantenimiento->aprobacion->motivo_rechazo,
                ] : null,
            ]);

        }, 'Error generando reporte de mantenimiento');
    }

    /**
     * Guardar firma del encargado
     * POST /api/v1/mantenimientos/{progId}/firma
     */
    public function guardarFirma(Request $request, int $progId): JsonResponse
    {
        return $this->ejecutar(function () use ($request, $progId) {

            $request->validate([
                'firma_base64' => 'required|string',
                'nombre_firmante' => 'nullable|string|max:200',
                'observacion' => 'nullable|string|max:1000',
            ]);

            $mantenimiento = MantProgramacion::where('prog_id', $progId)->first();

            if (!$mantenimiento) {
                return $this->notFoundResponse('Mantenimiento no encontrado');
            }

            // Buscar o crear registro de aprobación
            $aprobacion = DB::table('mant_aprobaciones')
                ->where('prog_id', $progId)
                ->first();

            if ($aprobacion) {
                DB::table('mant_aprobaciones')
                    ->where('prog_id', $progId)
                    ->update([
                        'firma_imagen' => $request->firma_base64,
                        'observacion_aprobacion' => $request->observacion,
                        'fecha_modificacion' => now(),
                    ]);
            } else {
                DB::table('mant_aprobaciones')->insert([
                    'prog_id' => $progId,
                    'tipo' => 'FIRMA_REPORTE',
                    'firma_imagen' => $request->firma_base64,
                    'observacion_aprobacion' => $request->observacion,
                    'jefe_operativo_id' => $this->usuarioActual()?->usu_id,
                    'fecha_aprobacion' => now(),
                    'estado' => 1,
                    'fecha_crea' => now(),
                ]);
            }

            return $this->successResponse([
                'message' => 'Firma guardada correctamente',
                'prog_id' => $progId,
            ]);

        }, 'Error guardando firma');
    }

    /**
     * Reporte consolidado
     * GET /api/v1/reportes/consolidado
     */
    #[OA\Get(
        path: "/api/v1/reportes/consolidado",
        summary: "Reporte consolidado",
        description: "Genera un reporte consolidado con totales por estado, técnico y peaje para un período de fechas",
        tags: ["Reportes"],
        security: [["sanctum" => []]],
        parameters: [
            new OA\Parameter(name: "fecha_desde", in: "query", required: true, schema: new OA\Schema(type: "string", format: "date")),
            new OA\Parameter(name: "fecha_hasta", in: "query", required: true, schema: new OA\Schema(type: "string", format: "date")),
            new OA\Parameter(name: "concesion_id", in: "query", required: false, schema: new OA\Schema(type: "integer")),
            new OA\Parameter(name: "peaje_id", in: "query", required: false, schema: new OA\Schema(type: "integer")),
            new OA\Parameter(name: "tecnico_id", in: "query", required: false, schema: new OA\Schema(type: "integer"))
        ],
        responses: [
            new OA\Response(
                response: 200,
                description: "Reporte consolidado",
                content: new OA\JsonContent(properties: [
                    new OA\Property(property: "success", type: "boolean", example: true),
                    new OA\Property(property: "data", type: "object", properties: [
                        new OA\Property(property: "periodo", type: "object", properties: [
                            new OA\Property(property: "desde", type: "string", format: "date"),
                            new OA\Property(property: "hasta", type: "string", format: "date")
                        ]),
                        new OA\Property(property: "resumen", type: "object", properties: [
                            new OA\Property(property: "total", type: "integer"),
                            new OA\Property(property: "completados", type: "integer"),
                            new OA\Property(property: "porcentaje", type: "number")
                        ]),
                        new OA\Property(property: "por_estado", type: "array", items: new OA\Items(type: "object")),
                        new OA\Property(property: "por_tecnico", type: "array", items: new OA\Items(type: "object")),
                        new OA\Property(property: "por_peaje", type: "array", items: new OA\Items(type: "object"))
                    ])
                ])
            ),
            new OA\Response(response: 422, description: "Error de validación")
        ]
    )]
    public function consolidado(Request $request): JsonResponse
    {
        return $this->ejecutar(function () use ($request) {

            $request->validate([
                'fecha_desde' => 'required|date',
                'fecha_hasta' => 'required|date|after_or_equal:fecha_desde',
                'concesion_id' => 'nullable|integer',
                'peaje_id' => 'nullable|integer',
                'tecnico_id' => 'nullable|integer',
            ]);

            $query = MantProgramacion::with([
                'estadoMantenimiento',
                'tecnico:usu_id,usu_nombre,usu_apellido',
                'centro:id_centro,nombre_centro,id_concesion',
                'centro.concesion:id_concesion,nombre',
            ])
            ->whereBetween('fecha_programada', [$request->fecha_desde, $request->fecha_hasta])
            ->activos();

            if ($request->filled('concesion_id')) {
                $query->whereHas('centro', fn($q) => $q->where('id_concesion', $request->concesion_id));
            }

            if ($request->filled('peaje_id')) {
                $query->where('id_centro', $request->peaje_id);
            }

            if ($request->filled('tecnico_id')) {
                $query->where('tecnico_asignado', $request->tecnico_id);
            }

            $mantenimientos = $query->get();

            // Agrupar por estado
            $porEstado = $mantenimientos->groupBy(fn($m) => $m->estadoMantenimiento->estado_codigo)
                ->map(fn($items, $estado) => [
                    'estado' => $items->first()->estadoMantenimiento->estado_nombre,
                    'color' => $items->first()->estadoMantenimiento->color_hex,
                    'cantidad' => $items->count(),
                ]);

            // Agrupar por técnico
            $porTecnico = $mantenimientos->groupBy('tecnico_asignado')
                ->map(fn($items, $tecnicoId) => [
                    'tecnico' => $items->first()->tecnico?->nombre_completo ?? 'Sin asignar',
                    'total' => $items->count(),
                    'completados' => $items->filter(fn($m) =>
                        in_array($m->estadoMantenimiento->estado_codigo, ['COMPLETADO', 'APROBADO'])
                    )->count(),
                ]);

            // Agrupar por peaje
            $porPeaje = $mantenimientos->groupBy('id_centro')
                ->map(fn($items, $centroId) => [
                    'peaje' => $items->first()->centro->nombre_centro,
                    'concesion' => $items->first()->centro->concesion->nombre,
                    'total' => $items->count(),
                    'completados' => $items->filter(fn($m) =>
                        in_array($m->estadoMantenimiento->estado_codigo, ['COMPLETADO', 'APROBADO'])
                    )->count(),
                ]);

            $totalCompletados = $mantenimientos->filter(fn($m) =>
                in_array($m->estadoMantenimiento->estado_codigo, ['COMPLETADO', 'APROBADO'])
            )->count();

            return $this->successResponse([
                'periodo' => [
                    'desde' => $request->fecha_desde,
                    'hasta' => $request->fecha_hasta,
                ],
                'resumen' => [
                    'total' => $mantenimientos->count(),
                    'completados' => $totalCompletados,
                    'porcentaje' => $mantenimientos->count() > 0
                        ? round(($totalCompletados / $mantenimientos->count()) * 100, 1)
                        : 0,
                ],
                'por_estado' => $porEstado->values(),
                'por_tecnico' => $porTecnico->values(),
                'por_peaje' => $porPeaje->values(),
            ]);

        }, 'Error generando reporte consolidado');
    }

    /**
     * Historial de un equipo
     * GET /api/v1/reportes/equipo/{inventarioId}
     *
     * Usa el SP: sp_historial_equipo
     */
    #[OA\Get(
        path: "/api/v1/reportes/equipo/{inventarioId}",
        summary: "Historial de un equipo",
        description: "Obtiene el historial de mantenimientos realizados sobre un equipo específico (últimos 50 registros). Usa el SP sp_historial_equipo",
        tags: ["Reportes"],
        security: [["sanctum" => []]],
        parameters: [
            new OA\Parameter(name: "inventarioId", in: "path", required: true, schema: new OA\Schema(type: "integer"))
        ],
        responses: [
            new OA\Response(
                response: 200,
                description: "Historial del equipo",
                content: new OA\JsonContent(properties: [
                    new OA\Property(property: "success", type: "boolean", example: true),
                    new OA\Property(property: "data", type: "object", properties: [
                        new OA\Property(property: "equipo", type: "object", nullable: true),
                        new OA\Property(property: "estadisticas", type: "object", properties: [
                            new OA\Property(property: "total_mantenimientos", type: "integer"),
                            new OA\Property(property: "total_movimientos", type: "integer")
                        ]),
                        new OA\Property(property: "historial", type: "array", items: new OA\Items(
                            properties: [
                                new OA\Property(property: "prog_id", type: "integer"),
                                new OA\Property(property: "fecha", type: "string", format: "date"),
                                new OA\Property(property: "mant_estado", type: "string"),
                                new OA\Property(property: "estado_equipo", type: "string"),
                                new OA\Property(property: "color", type: "string"),
                                new OA\Property(property: "observacion", type: "string"),
                                new OA\Property(property: "peaje", type: "string"),
                                new OA\Property(property: "tecnico", type: "string")
                            ]
                        ))
                    ])
                ])
            )
        ]
    )]
    public function historialEquipo(int $inventarioId): JsonResponse
    {
        return $this->ejecutar(function () use ($inventarioId) {

            // Llamar al Stored Procedure
            $resultado = $this->ejecutarSP('sp_historial_equipo', [$inventarioId]);
            $respuesta = $this->parsearRespuestaSP($resultado);

            // Obtener historial de mantenimientos
            $historial = DB::table('mant_checklist_respuestas as cr')
                ->join('mant_programacion as mp', 'cr.prog_id', '=', 'mp.prog_id')
                ->join('mant_estados as me', 'mp.estado_id', '=', 'me.estado_id')
                ->join('mant_estado_equipos as mee', 'cr.estado_equipo_id', '=', 'mee.estado_equipo_id')
                ->join('peaje_centro as pc', 'mp.id_centro', '=', 'pc.id_centro')
                ->join('usuarios as u', 'cr.usuario_registra', '=', 'u.usu_id')
                ->where('cr.inventario_id', $inventarioId)
                ->select([
                    'mp.prog_id',
                    'mp.fecha_programada',
                    'me.estado_nombre as mant_estado',
                    'mee.nombre as estado_equipo',
                    'mee.color_hex',
                    'cr.observacion',
                    'pc.nombre_centro as peaje',
                    DB::raw("CONCAT(u.usu_nombre, ' ', u.usu_apellido) as tecnico"),
                    'cr.fecha_registro',
                ])
                ->orderBy('cr.fecha_registro', 'desc')
                ->limit(50)
                ->get();

            return $this->successResponse([
                'equipo' => $respuesta['data']['equipo'] ?? null,
                'estadisticas' => [
                    'total_mantenimientos' => $respuesta['data']['mantenimientos'] ?? $historial->count(),
                    'total_movimientos' => $respuesta['data']['movimientos'] ?? 0,
                ],
                'historial' => $historial->map(fn($h) => [
                    'prog_id' => $h->prog_id,
                    'fecha' => $h->fecha_programada,
                    'mant_estado' => $h->mant_estado,
                    'estado_equipo' => $h->estado_equipo,
                    'color' => $h->color_hex,
                    'observacion' => $h->observacion,
                    'peaje' => $h->peaje,
                    'tecnico' => $h->tecnico,
                ]),
            ]);

        }, 'Error obteniendo historial del equipo');
    }
}
