<?php

namespace App\Console\Commands;

use App\Models\Configuracion;
use App\Models\Equipo;
use App\Models\EstadoOrden;
use App\Models\OrdenItem;
use App\Models\OrdenLog;
use App\Models\OrdenTrabajo;
use App\Models\PlanItem;
use App\Models\PlanMantenimiento;
use Illuminate\Console\Command;
use Illuminate\Support\Carbon;

class RevisarHorometro extends Command
{
    protected $signature = 'mantenimiento:revisar-horometro
                            {--equipo= : Solo revisar un equipo específico (ID)}
                            {--dry-run : Solo mostrar lo que se generaría, sin crear OT}';

    protected $description = 'Revisa los horómetros de los equipos y genera OT preventivas cuando se cruza un umbral PM (360, 720, 4320, 8640 h).';

    private array $umbrales = [
        'pm_360'  => 360,
        'pm_720'  => 720,
        'pm_4320' => 4320,
        'pm_8640' => 8640,
    ];

    public function handle(): int
    {
        $dry = (bool) $this->option('dry-run');
        $equipoId = $this->option('equipo');

        $q = Equipo::with(['area'])->where('activo', 1);
        if ($equipoId) $q->where('id', $equipoId);
        $equipos = $q->get();

        $this->info("Revisando " . $equipos->count() . " equipo(s). " . ($dry ? '[DRY-RUN]' : ''));

        $generadas = 0;
        $estadoPen = EstadoOrden::where('codigo','PEN')->first();

        foreach ($equipos as $equipo) {
            $horoActual = (float) $equipo->horometro_actual;
            if ($horoActual <= 0) continue;

            // Buscar el plan preventivo de este equipo
            $plan = PlanMantenimiento::where('equipo_id', $equipo->id)
                ->where('clase','preventivo')->where('activo', 1)->first();
            if (!$plan) continue;

            foreach ($this->umbrales as $cmp => $umbral) {
                $colEquipo = 'ultimo_' . $cmp;
                $ultimoPm = (float) ($equipo->$colEquipo ?? 0);
                if ($ultimoPm <= 0) continue;          // Aún no se ha hecho ningún PM de este tipo
                $delta = $horoActual - $ultimoPm;
                if ($delta < $umbral) continue;         // No toca todavía

                // ¿Hay items del plan que requieran este PM?
                $items = PlanItem::where('plan_id', $plan->id)->where('activo', 1)
                    ->where($cmp, 1)->orderBy('numero_item')->get();
                if ($items->isEmpty()) continue;

                // ¿Ya existe una OT abierta para este equipo/pm_tipo?
                $existe = OrdenTrabajo::where('equipo_id', $equipo->id)
                    ->where('pm_tipo', (string) $umbral)
                    ->where('horometro_disparo', '>=', $ultimoPm)
                    ->whereHas('estado', fn ($e) => $e->whereNotIn('codigo', ['EJE','APR','CAN']))
                    ->exists();
                if ($existe) {
                    $this->line("  [skip] {$equipo->codigo} PM {$umbral}h ya tiene OT abierta.");
                    continue;
                }

                $this->line(sprintf(
                    "  ▶ %s PM %dh — última %.0f, actual %.0f, delta %.0f (%d ítems)",
                    $equipo->codigo, $umbral, $ultimoPm, $horoActual, $delta, $items->count()
                ));

                if ($dry) { $generadas++; continue; }

                $orden = OrdenTrabajo::create([
                    'codigo' => $this->generarCodigo(),
                    'clase' => 'preventivo',
                    'pm_tipo' => (string) $umbral,
                    'plan_id' => $plan->id,
                    'area_id' => $equipo->area_id,
                    'sistema_id' => $equipo->sistema_id,
                    'equipo_id' => $equipo->id,
                    'estado_id' => $estadoPen?->id,
                    'fecha_programada' => Carbon::today(),
                    'horometro_disparo' => $horoActual,
                    'descripcion' => "Generada automáticamente al cruzar umbral PM {$umbral}h (horómetro {$horoActual}h, última PM a {$ultimoPm}h).",
                    'creado_por' => null,
                ]);

                foreach ($items as $pi) {
                    OrdenItem::create([
                        'orden_id' => $orden->id,
                        'plan_item_id' => $pi->id,
                        'numero_item' => $pi->numero_item,
                        'descripcion' => $pi->descripcion,
                        'estado_item' => 'pendiente',
                        'lila_l_limpieza' => $pi->lila_l_limpieza,
                        'lila_i_inspeccion' => $pi->lila_i_inspeccion,
                        'lila_l_lubricacion' => $pi->lila_l_lubricacion,
                        'lila_a_ajuste' => $pi->lila_a_ajuste,
                    ]);
                }

                OrdenLog::create([
                    'orden_id' => $orden->id,
                    'accion' => 'generada_por_horometro',
                    'estado_nuevo' => 'PEN',
                    'detalle' => "PM {$umbral}h — horómetro {$horoActual} (anterior {$ultimoPm})",
                ]);

                $generadas++;
            }
        }

        $this->info("Total generadas: {$generadas}");
        return self::SUCCESS;
    }

    private function generarCodigo(): string
    {
        $prefijo = Configuracion::obtener('prefijo_orden_preventiva', 'OTP');
        $anio = now()->year;
        $count = OrdenTrabajo::where('clase','preventivo')->whereYear('created_at',$anio)->count() + 1;
        return $prefijo . '-' . $anio . '-' . str_pad((string) $count, 5, '0', STR_PAD_LEFT);
    }
}
