<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Api\ApiController;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class CalendarioController extends ApiController
{
    /**
     * Ver calendario de mantenimientos
     * GET /api/v1/calendario
     */
    public function index(Request $request): JsonResponse
    {
        return $this->ejecutar(function () use ($request) {

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

            $query = DB::table('mant_programacion as mp')
                ->join('mant_estados as me', 'mp.estado_id', '=', 'me.estado_id')
                ->join('peaje_centro as pc', 'mp.id_centro', '=', 'pc.id_centro')
                ->join('concesiones as c', 'pc.id_concesion', '=', 'c.id_concesion')
                ->leftJoin('via_subcentro as vs', 'mp.via_id', '=', 'vs.via_id')
                ->leftJoin('usuarios as u', 'mp.tecnico_asignado', '=', 'u.usu_id')
                ->select([
                    'mp.prog_id',
                    'mp.fecha_programada',
                    'mp.fecha_fin',
                    'mp.observaciones',
                    'mp.usa_backup',
                    'me.estado_id',
                    'me.estado_codigo',
                    'me.estado_nombre',
                    'me.color_hex',
                    'pc.id_centro',
                    'pc.nombre_centro',
                    'c.id_concesion',
                    'c.nombre as concesion_nombre',
                    'vs.via_id',
                    'vs.nombre as via_nombre',
                    'u.usu_id as tecnico_id',
                    'u.usu_nombre as tecnico_nombre',
                    'u.usu_apellido as tecnico_apellido',
                ])
                ->where(function ($q) use ($request) {
                    $q->whereBetween('mp.fecha_programada', [$request->fecha_inicio, $request->fecha_fin])
                        ->orWhereBetween('mp.fecha_fin', [$request->fecha_inicio, $request->fecha_fin]);
                })
                ->where('mp.estado', 1);

            // Filtros opcionales
            if ($request->filled('concesion_id')) {
                $query->where('c.id_concesion', $request->concesion_id);
            }
            if ($request->filled('peaje_id')) {
                $query->where('pc.id_centro', $request->peaje_id);
            }
            if ($request->filled('tecnico_id')) {
                $query->where('mp.tecnico_asignado', $request->tecnico_id);
            }
            if ($request->filled('estado_id')) {
                $query->where('mp.estado_id', $request->estado_id);
            }

            $mantenimientos = $query->orderBy('mp.fecha_programada', 'asc')->get();

            // Formatear para FullCalendar
            $eventos = $mantenimientos->map(function ($m) {
                return [
                    'id' => $m->prog_id,
                    'title' => $m->nombre_centro . ($m->via_nombre ? " - {$m->via_nombre}" : ''),
                    'start' => $m->fecha_programada,
                    'end' => $m->fecha_fin ? Carbon::parse($m->fecha_fin)->addDay()->format('Y-m-d') : null,
                    'backgroundColor' => $m->color_hex ?? '#3788d8',
                    'borderColor' => $m->color_hex ?? '#3788d8',
                    'extendedProps' => [
                        'estado_codigo' => $m->estado_codigo,
                        'estado_nombre' => $m->estado_nombre,
                        'concesion' => $m->concesion_nombre,
                        'peaje_id' => $m->id_centro,
                        'peaje' => $m->nombre_centro,
                        'via_id' => $m->via_id,
                        'via' => $m->via_nombre,
                        'tecnico_id' => $m->tecnico_id,
                        'tecnico' => $m->tecnico_nombre
                            ? "{$m->tecnico_nombre} {$m->tecnico_apellido}"
                            : 'Sin asignar',
                        'usa_backup' => (bool) $m->usa_backup,
                        'fecha_inicio' => $m->fecha_programada,
                        'fecha_fin' => $m->fecha_fin,
                    ],
                ];
            });

            return $this->successResponse([
                'eventos' => $eventos,
                'total' => $eventos->count(),
            ]);

        }, 'Error obteniendo calendario');
    }

    // ============================================================
    // PLANTILLA SEMANAL
    // ============================================================

    /**
     * Obtener plantilla del mes
     * GET /api/v1/calendario/plantilla
     */
    public function getPlantilla(Request $request): JsonResponse
    {
        return $this->ejecutar(function () use ($request) {

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

            $plantillas = DB::table('mant_plantilla_semanal as p')
                ->leftJoin('usuarios as ut', 'p.tecnico_principal', '=', 'ut.usu_id')
                ->leftJoin('usuarios as ub1', 'p.backup_1', '=', 'ub1.usu_id')
                ->leftJoin('usuarios as ub2', 'p.backup_2', '=', 'ub2.usu_id')
                ->where('p.anio', $request->anio)
                ->where('p.mes', $request->mes)
                ->where('p.estado', 1)
                ->select([
                    'p.*',
                    'ut.usu_nombre as tecnico_nombre',
                    'ut.usu_apellido as tecnico_apellido',
                    'ub1.usu_nombre as backup1_nombre',
                    'ub1.usu_apellido as backup1_apellido',
                    'ub2.usu_nombre as backup2_nombre',
                    'ub2.usu_apellido as backup2_apellido',
                ])
                ->orderBy('p.semana_numero')
                ->get();

            $plantillas = $plantillas->map(function ($p) {
                return [
                    'plantilla_id' => $p->plantilla_id,
                    'semana_numero' => $p->semana_numero,
                    'fecha_inicio' => $p->fecha_inicio,
                    'fecha_fin' => $p->fecha_fin,
                    'tecnico_principal' => [
                        'id' => $p->tecnico_principal,
                        'nombre' => "{$p->tecnico_nombre} {$p->tecnico_apellido}",
                    ],
                    'backup_1' => $p->backup_1 ? [
                        'id' => $p->backup_1,
                        'nombre' => "{$p->backup1_nombre} {$p->backup1_apellido}",
                    ] : null,
                    'backup_2' => $p->backup_2 ? [
                        'id' => $p->backup_2,
                        'nombre' => "{$p->backup2_nombre} {$p->backup2_apellido}",
                    ] : null,
                    'observaciones' => $p->observaciones,
                ];
            });

            return $this->successResponse([
                'anio' => $request->anio,
                'mes' => $request->mes,
                'semanas' => $plantillas,
            ]);

        }, 'Error obteniendo plantilla');
    }

    /**
     * Generar plantilla del mes (crear semanas vacías o con técnicos)
     * POST /api/v1/calendario/plantilla/generar
     */
    public function generarPlantilla(Request $request): JsonResponse
    {
        return $this->ejecutar(function () use ($request) {

            $request->validate([
                'anio' => 'required|integer|min:2024|max:2030',
                'mes' => 'required|integer|min:1|max:12',
                'semanas' => 'required|array|min:1',
                'semanas.*.semana_numero' => 'required|integer|min:1|max:6',
                'semanas.*.fecha_inicio' => 'required|date',
                'semanas.*.fecha_fin' => 'required|date|after_or_equal:semanas.*.fecha_inicio',
                'semanas.*.tecnico_principal' => 'required|integer|exists:usuarios,usu_id',
                'semanas.*.backup_1' => 'nullable|integer|exists:usuarios,usu_id',
                'semanas.*.backup_2' => 'nullable|integer|exists:usuarios,usu_id',
                'semanas.*.observaciones' => 'nullable|string|max:500',
            ]);

            // Verificar si ya existe plantilla
            $existe = DB::table('mant_plantilla_semanal')
                ->where('anio', $request->anio)
                ->where('mes', $request->mes)
                ->where('estado', 1)
                ->exists();

            if ($existe) {
                return $this->errorResponse(
                    'Ya existe una plantilla para este mes. Elimínela primero o edite las semanas individualmente.',
                    400
                );
            }

            DB::beginTransaction();
            try {
                foreach ($request->semanas as $semana) {
                    DB::table('mant_plantilla_semanal')->insert([
                        'anio' => $request->anio,
                        'mes' => $request->mes,
                        'semana_numero' => $semana['semana_numero'],
                        'fecha_inicio' => $semana['fecha_inicio'],
                        'fecha_fin' => $semana['fecha_fin'],
                        'tecnico_principal' => $semana['tecnico_principal'],
                        'backup_1' => $semana['backup_1'] ?? null,
                        'backup_2' => $semana['backup_2'] ?? null,
                        'observaciones' => $semana['observaciones'] ?? null,
                        'estado' => 1,
                        'usuario_crea' => $this->usuarioId(),
                        'fecha_crea' => now(),
                    ]);
                }

                DB::commit();

                $this->registrarAuditoria('CREAR_PLANTILLA', 'mant_plantilla_semanal', null, null, [
                    'anio' => $request->anio,
                    'mes' => $request->mes,
                    'semanas' => count($request->semanas),
                ]);

                return $this->createdResponse([
                    'anio' => $request->anio,
                    'mes' => $request->mes,
                    'semanas_creadas' => count($request->semanas),
                ], 'Plantilla generada exitosamente');

            } catch (\Exception $e) {
                DB::rollBack();
                throw $e;
            }

        }, 'Error generando plantilla');
    }

    /**
     * Actualizar semana de plantilla
     * PUT /api/v1/calendario/plantilla/{id}
     */
    public function updatePlantilla(Request $request, int $id): JsonResponse
    {
        return $this->ejecutar(function () use ($request, $id) {

            $plantilla = DB::table('mant_plantilla_semanal')
                ->where('plantilla_id', $id)
                ->where('estado', 1)
                ->first();

            if (!$plantilla) {
                return $this->notFoundResponse('Plantilla no encontrada');
            }

            $request->validate([
                'fecha_inicio' => 'sometimes|date',
                'fecha_fin' => 'sometimes|date',
                'tecnico_principal' => 'sometimes|integer|exists:usuarios,usu_id',
                'backup_1' => 'nullable|integer|exists:usuarios,usu_id',
                'backup_2' => 'nullable|integer|exists:usuarios,usu_id',
                'observaciones' => 'nullable|string|max:500',
            ]);

            $datosAnteriores = (array) $plantilla;

            $actualizar = array_filter([
                'fecha_inicio' => $request->fecha_inicio,
                'fecha_fin' => $request->fecha_fin,
                'tecnico_principal' => $request->tecnico_principal,
                'backup_1' => $request->backup_1,
                'backup_2' => $request->backup_2,
                'observaciones' => $request->observaciones,
                'usuario_modifica' => $this->usuarioId(),
                'fecha_modifica' => now(),
            ], fn($v) => $v !== null);

            DB::table('mant_plantilla_semanal')
                ->where('plantilla_id', $id)
                ->update($actualizar);

            $this->registrarAuditoria('ACTUALIZAR_PLANTILLA', 'mant_plantilla_semanal', $id, $datosAnteriores, $actualizar);

            return $this->successResponse([
                'plantilla_id' => $id,
            ], 'Plantilla actualizada exitosamente');

        }, 'Error actualizando plantilla');
    }

    /**
     * Eliminar plantilla completa del mes
     * DELETE /api/v1/calendario/plantilla
     */
    public function deletePlantilla(Request $request): JsonResponse
    {
        return $this->ejecutar(function () use ($request) {

            $request->validate([
                'anio' => 'required|integer',
                'mes' => 'required|integer',
            ]);

            $affected = DB::table('mant_plantilla_semanal')
                ->where('anio', $request->anio)
                ->where('mes', $request->mes)
                ->update([
                    'estado' => 0,
                    'usuario_modifica' => $this->usuarioId(),
                    'fecha_modifica' => now(),
                ]);

            $this->registrarAuditoria('ELIMINAR_PLANTILLA', 'mant_plantilla_semanal', null, null, [
                'anio' => $request->anio,
                'mes' => $request->mes,
            ]);

            return $this->successResponse([
                'semanas_eliminadas' => $affected,
            ], 'Plantilla eliminada exitosamente');

        }, 'Error eliminando plantilla');
    }

    // ============================================================
    // PROGRAMACIÓN DE MANTENIMIENTOS
    // ============================================================

    /**
     * Programar mantenimiento
     * POST /api/v1/calendario/programar
     */
    public function programar(Request $request): JsonResponse
    {
        return $this->ejecutar(function () use ($request) {

            $request->validate([
                'id_centro' => 'required|integer|exists:peaje_centro,id_centro',
                'via_id' => 'nullable|integer|exists:via_subcentro,via_id',
                'fecha_inicio' => 'required|date',
                'fecha_fin' => 'nullable|date|after_or_equal:fecha_inicio',
                'tecnico_id' => 'nullable|integer|exists:usuarios,usu_id',
                'usar_plantilla' => 'nullable|boolean',
                'observaciones' => 'nullable|string|max:500',
            ]);

            // Validar que la vía pertenece al peaje (si se envía)
            if ($request->filled('via_id')) {
                $viaValida = DB::table('via_subcentro')
                    ->where('via_id', $request->via_id)
                    ->where('id_centro', $request->id_centro)
                    ->where('estado', 1)
                    ->exists();

                if (!$viaValida) {
                    return $this->validationErrorResponse(
                        ['via_id' => ['La vía no pertenece al peaje seleccionado']],
                        'Datos de entrada inválidos'
                    );
                }
            }

            $tecnicoId = $request->tecnico_id;
            $plantillaId = null;
            $usaBackup = false;

            // Si usar_plantilla = true, buscar técnico de la plantilla
            if ($request->input('usar_plantilla', true) && !$request->filled('tecnico_id')) {
                $fecha = Carbon::parse($request->fecha_inicio);

                $plantilla = DB::table('mant_plantilla_semanal')
                    ->where('anio', $fecha->year)
                    ->where('mes', $fecha->month)
                    ->where('fecha_inicio', '<=', $request->fecha_inicio)
                    ->where('fecha_fin', '>=', $request->fecha_inicio)
                    ->where('estado', 1)
                    ->first();

                if ($plantilla) {
                    $tecnicoId = $plantilla->tecnico_principal;
                    $plantillaId = $plantilla->plantilla_id;
                }
            }

            if (!$tecnicoId) {
                return $this->validationErrorResponse(
                    ['tecnico_id' => ['Debe asignar un técnico o tener plantilla configurada']],
                    'Datos de entrada inválidos'
                );
            }

            // Obtener estado PROGRAMADO
            $estadoProgramado = DB::table('mant_estados')
                ->where('estado_codigo', 'PROGRAMADO')
                ->first();

            if (!$estadoProgramado) {
                return $this->serverErrorResponse();
            }

            DB::beginTransaction();
            try {
                $progId = DB::table('mant_programacion')->insertGetId([
                    'plantilla_id' => $plantillaId,
                    'id_centro' => $request->id_centro,
                    'via_id' => $request->via_id,
                    'fecha_programada' => $request->fecha_inicio,
                    'fecha_fin' => $request->fecha_fin ?? $request->fecha_inicio,
                    'tecnico_asignado' => $tecnicoId,
                    'usa_backup' => $usaBackup,
                    'estado_id' => $estadoProgramado->estado_id,
                    'observaciones' => $request->observaciones,
                    'estado' => 1,
                    'fecha_crea' => now(),
                    'usuario_crea' => $this->usuarioId(),
                ]);

                // Historial de estados
                DB::table('mant_estado_historial')->insert([
                    'prog_id' => $progId,
                    'estado_id' => $estadoProgramado->estado_id,
                    'fecha_cambio' => now(),
                    'usuario_cambio' => $this->usuarioId(),
                    'observaciones' => 'Mantenimiento programado',
                ]);

                DB::commit();

                $this->registrarAuditoria('PROGRAMAR', 'mant_programacion', $progId, null, [
                    'fecha_inicio' => $request->fecha_inicio,
                    'fecha_fin' => $request->fecha_fin,
                    'tecnico' => $tecnicoId,
                ]);

                return $this->createdResponse([
                    'prog_id' => $progId,
                    'fecha_inicio' => $request->fecha_inicio,
                    'fecha_fin' => $request->fecha_fin ?? $request->fecha_inicio,
                    'tecnico_id' => $tecnicoId,
                ], 'Mantenimiento programado exitosamente');

            } catch (\Exception $e) {
                DB::rollBack();
                throw $e;
            }

        }, 'Error programando mantenimiento');
    }

    /**
     * Ver detalle de mantenimiento programado
     * GET /api/v1/calendario/{id}
     */
    public function show(int $id): JsonResponse
    {
        return $this->ejecutar(function () use ($id) {

            $prog = DB::table('mant_programacion as mp')
                ->join('mant_estados as me', 'mp.estado_id', '=', 'me.estado_id')
                ->join('peaje_centro as pc', 'mp.id_centro', '=', 'pc.id_centro')
                ->join('concesiones as c', 'pc.id_concesion', '=', 'c.id_concesion')
                ->leftJoin('via_subcentro as vs', 'mp.via_id', '=', 'vs.via_id')
                ->leftJoin('usuarios as u', 'mp.tecnico_asignado', '=', 'u.usu_id')
                ->where('mp.prog_id', $id)
                ->select([
                    'mp.*',
                    'me.estado_codigo',
                    'me.estado_nombre',
                    'me.color_hex',
                    'pc.nombre_centro',
                    'pc.id_concesion',
                    'c.nombre as concesion_nombre',
                    'vs.nombre as via_nombre',
                    'u.usu_nombre as tecnico_nombre',
                    'u.usu_apellido as tecnico_apellido',
                ])
                ->first();

            if (!$prog) {
                return $this->notFoundResponse('Programación no encontrada');
            }

            // Historial de estados
            $historial = DB::table('mant_estado_historial as h')
                ->join('mant_estados as me', 'h.estado_id', '=', 'me.estado_id')
                ->leftJoin('usuarios as u', 'h.usuario_cambio', '=', 'u.usu_id')
                ->where('h.prog_id', $id)
                ->select([
                    'h.*',
                    'me.estado_codigo',
                    'me.estado_nombre',
                    'u.usu_nombre',
                    'u.usu_apellido',
                ])
                ->orderBy('h.fecha_cambio', 'desc')
                ->get();

            return $this->successResponse([
                'programacion' => [
                    'prog_id' => $prog->prog_id,
                    'fecha_inicio' => $prog->fecha_programada,
                    'fecha_fin' => $prog->fecha_fin,
                    'observaciones' => $prog->observaciones,
                    'estado' => [
                        'codigo' => $prog->estado_codigo,
                        'nombre' => $prog->estado_nombre,
                        'color' => $prog->color_hex,
                    ],
                    'peaje' => [
                        'id' => $prog->id_centro,
                        'nombre' => $prog->nombre_centro,
                    ],
                    'concesion' => [
                        'id' => $prog->id_concesion,
                        'nombre' => $prog->concesion_nombre,
                    ],
                    'via' => $prog->via_id ? [
                        'id' => $prog->via_id,
                        'nombre' => $prog->via_nombre,
                    ] : null,
                    'tecnico' => [
                        'id' => $prog->tecnico_asignado,
                        'nombre' => "{$prog->tecnico_nombre} {$prog->tecnico_apellido}",
                    ],
                    'usa_backup' => (bool) $prog->usa_backup,
                ],
                'historial' => $historial->map(fn($h) => [
                    'estado' => $h->estado_nombre,
                    'fecha' => $h->fecha_cambio,
                    'usuario' => "{$h->usu_nombre} {$h->usu_apellido}",
                    'observaciones' => $h->observaciones,
                    'latitud' => $h->latitud,
                    'longitud' => $h->longitud,
                ]),
            ]);

        }, 'Error obteniendo programación');
    }

    /**
     * Actualizar mantenimiento programado
     * PUT /api/v1/calendario/{id}
     */
    public function update(Request $request, int $id): JsonResponse
    {
        return $this->ejecutar(function () use ($request, $id) {

            $prog = DB::table('mant_programacion')
                ->where('prog_id', $id)
                ->where('estado', 1)
                ->first();

            if (!$prog) {
                return $this->notFoundResponse('Programación no encontrada');
            }

            $request->validate([
                'fecha_inicio' => 'sometimes|date',
                'fecha_fin' => 'sometimes|date',
                'tecnico_id' => 'sometimes|integer|exists:usuarios,usu_id',
                'via_id' => 'nullable|integer|exists:via_subcentro,via_id',
                'observaciones' => 'nullable|string|max:500',
            ]);

            $datosAnteriores = (array) $prog;

            $actualizar = [
                'usuario_modifica' => $this->usuarioId(),
                'fecha_modifica' => now(),
            ];

            if ($request->has('fecha_inicio')) {
                $actualizar['fecha_programada'] = $request->fecha_inicio;
            }
            if ($request->has('fecha_fin')) {
                $actualizar['fecha_fin'] = $request->fecha_fin;
            }
            if ($request->has('tecnico_id')) {
                $actualizar['tecnico_asignado'] = $request->tecnico_id;
            }
            if ($request->has('via_id')) {
                $actualizar['via_id'] = $request->via_id;
            }
            if ($request->has('observaciones')) {
                $actualizar['observaciones'] = $request->observaciones;
            }

            DB::table('mant_programacion')
                ->where('prog_id', $id)
                ->update($actualizar);

            $this->registrarAuditoria('ACTUALIZAR', 'mant_programacion', $id, $datosAnteriores, $actualizar);

            return $this->successResponse([
                'prog_id' => $id,
            ], 'Programación actualizada exitosamente');

        }, 'Error actualizando programación');
    }

    /**
     * Cancelar mantenimiento
     * DELETE /api/v1/calendario/{id}
     */
    public function cancelar(Request $request, int $id): JsonResponse
    {
        return $this->ejecutar(function () use ($request, $id) {

            $request->validate([
                'motivo' => 'required|string|min:10|max:500',
            ]);

            $prog = DB::table('mant_programacion')
                ->where('prog_id', $id)
                ->where('estado', 1)
                ->first();

            if (!$prog) {
                return $this->notFoundResponse('Programación no encontrada');
            }

            DB::beginTransaction();
            try {
                DB::table('mant_programacion')
                    ->where('prog_id', $id)
                    ->update([
                        'motivo_cancelacion' => $request->motivo,
                        'estado' => 0,
                        'fecha_modifica' => now(),
                        'usuario_modifica' => $this->usuarioId(),
                    ]);

                DB::table('mant_estado_historial')->insert([
                    'prog_id' => $id,
                    'estado_id' => $prog->estado_id,
                    'fecha_cambio' => now(),
                    'usuario_cambio' => $this->usuarioId(),
                    'observaciones' => "Cancelado: {$request->motivo}",
                ]);

                DB::commit();

                $this->registrarAuditoria('CANCELAR', 'mant_programacion', $id, null, [
                    'motivo' => $request->motivo,
                ]);

                return $this->successResponse([
                    'prog_id' => $id,
                ], 'Mantenimiento cancelado exitosamente');

            } catch (\Exception $e) {
                DB::rollBack();
                throw $e;
            }

        }, 'Error cancelando mantenimiento');
    }

    // ============================================================
    // UTILIDADES
    // ============================================================

    /**
     * Obtener técnicos disponibles
     * GET /api/v1/calendario/tecnicos
     */
    public function getTecnicos(): JsonResponse
    {
        return $this->ejecutar(function () {

            $tecnicos = DB::table('usuarios as u')
                ->join('perfil as p', 'u.per_id', '=', 'p.per_id')
                ->whereIn('p.per_nombre', ['TECNICOS', 'TECNICO', 'Tecnico', 'Tecnicos'])
                ->where('u.usu_estado', 1)
                ->select(['u.usu_id', 'u.usu_nombre', 'u.usu_apellido', 'u.usu_cedula'])
                ->orderBy('u.usu_nombre')
                ->get();

            return $this->successResponse([
                'tecnicos' => $tecnicos->map(fn($t) => [
                    'id' => $t->usu_id,
                    'nombre' => "{$t->usu_nombre} {$t->usu_apellido}",
                    'cedula' => $t->usu_cedula,
                ]),
            ]);

        }, 'Error obteniendo técnicos');
    }

    /**
     * Obtener resumen del mes
     * GET /api/v1/calendario/resumen
     */
    public function resumen(Request $request): JsonResponse
    {
        return $this->ejecutar(function () use ($request) {

            $request->validate([
                'anio' => 'required|integer',
                'mes' => 'required|integer',
            ]);

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

            // Total programados
            $totalProgramados = DB::table('mant_programacion')
                ->whereBetween('fecha_programada', [$fechaInicio, $fechaFin])
                ->where('estado', 1)
                ->count();

            // Por estado
            $porEstado = DB::table('mant_programacion as mp')
                ->join('mant_estados as me', 'mp.estado_id', '=', 'me.estado_id')
                ->whereBetween('mp.fecha_programada', [$fechaInicio, $fechaFin])
                ->where('mp.estado', 1)
                ->groupBy('me.estado_codigo', 'me.estado_nombre', 'me.color_hex')
                ->select([
                    'me.estado_codigo',
                    'me.estado_nombre',
                    'me.color_hex',
                    DB::raw('COUNT(*) as total'),
                ])
                ->get();

            // Por técnico
            $porTecnico = DB::table('mant_programacion as mp')
                ->join('usuarios as u', 'mp.tecnico_asignado', '=', 'u.usu_id')
                ->whereBetween('mp.fecha_programada', [$fechaInicio, $fechaFin])
                ->where('mp.estado', 1)
                ->groupBy('u.usu_id', 'u.usu_nombre', 'u.usu_apellido')
                ->select([
                    'u.usu_id',
                    'u.usu_nombre',
                    'u.usu_apellido',
                    DB::raw('COUNT(*) as total'),
                ])
                ->get();

            return $this->successResponse([
                'anio' => $request->anio,
                'mes' => $request->mes,
                'total_programados' => $totalProgramados,
                'por_estado' => $porEstado,
                'por_tecnico' => $porTecnico->map(fn($t) => [
                    'id' => $t->usu_id,
                    'nombre' => "{$t->usu_nombre} {$t->usu_apellido}",
                    'total' => $t->total,
                ]),
            ]);

        }, 'Error obteniendo resumen');
    }
}
