<?php

namespace App\Http\Controllers;

use App\Models\EstadoOrden;
use App\Models\OrdenLog;
use App\Models\OrdenTrabajo;
use App\Models\ParoPlanta;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;

class ParoPlantaController extends Controller
{
    public function index()
    {
        $activos = ParoPlanta::with('usuario')->whereNull('fecha_fin')
            ->orderBy('fecha_inicio')->get();
        $historial = ParoPlanta::with('usuario')->whereNotNull('fecha_fin')
            ->orderByDesc('fecha_fin')->paginate(25);
        return view('paros.index', compact('activos','historial'));
    }

    public function create()
    {
        return view('paros.form', ['paro' => new ParoPlanta(['fecha_inicio' => now()->toDateString()])]);
    }

    public function store(Request $r)
    {
        $datos = $r->validate([
            'fecha_inicio' => 'required|date',
            'motivo' => 'required|string|max:200',
            'descripcion' => 'nullable|string',
        ]);
        $datos['usuario_id'] = auth()->id();
        ParoPlanta::create($datos);
        return redirect()->route('paros.index')->with('exito','Paro de planta registrado.');
    }

    public function edit(ParoPlanta $paro)
    {
        return view('paros.form', compact('paro'));
    }

    public function update(Request $r, ParoPlanta $paro)
    {
        if ($paro->aplicado) {
            return back()->with('error','Este paro ya fue aplicado, no se puede editar.');
        }
        $paro->update($r->validate([
            'fecha_inicio' => 'required|date',
            'motivo' => 'required|string|max:200',
            'descripcion' => 'nullable|string',
        ]));
        return redirect()->route('paros.index')->with('exito','Paro actualizado.');
    }

    public function destroy(ParoPlanta $paro)
    {
        if ($paro->aplicado) {
            return back()->with('error','Este paro ya fue aplicado, no se puede eliminar.');
        }
        $paro->delete();
        return back()->with('exito','Paro eliminado.');
    }

    /**
     * Cierra el paro: registra fecha_fin, calcula duración y desplaza
     * todas las OT pendientes/reprogramadas con fecha_programada >= fecha_inicio.
     */
    public function cerrar(Request $r, ParoPlanta $paro)
    {
        if ($paro->aplicado) {
            return back()->with('error','Este paro ya fue cerrado y aplicado.');
        }
        $r->validate(['fecha_fin' => 'required|date|after_or_equal:' . $paro->fecha_inicio->toDateString()]);
        $fechaFin = Carbon::parse($r->fecha_fin);

        $dias = (int) $paro->fecha_inicio->diffInDays($fechaFin);
        if ($dias <= 0) {
            $paro->fecha_fin = $fechaFin;
            $paro->duracion_dias = 0;
            $paro->aplicado = true;
            $paro->save();
            return back()->with('exito','Paro cerrado sin desplazar OT (duración 0 días).');
        }

        $estadoREP = EstadoOrden::where('codigo','REP')->value('id');
        $afectadas = 0;

        DB::transaction(function () use ($paro, $fechaFin, $dias, $estadoREP, &$afectadas) {
            $ots = OrdenTrabajo::whereHas('estado', fn ($e) => $e->whereIn('codigo', ['PEN','REP']))
                ->whereDate('fecha_programada', '>=', $paro->fecha_inicio)
                ->get();

            foreach ($ots as $ot) {
                $fechaOriginal = $ot->fecha_programada;
                $ot->fecha_programada = $fechaOriginal->copy()->addDays($dias);
                $ot->estado_id = $estadoREP;
                $ot->save();

                OrdenLog::create([
                    'orden_id' => $ot->id,
                    'usuario_id' => auth()->id(),
                    'accion' => 'desplazada_paro',
                    'detalle' => "Desplazada {$dias} días por paro #{$paro->id} ({$paro->motivo}). "
                               . "Original: {$fechaOriginal->format('d/m/Y')}",
                ]);
                $afectadas++;
            }

            $paro->fecha_fin = $fechaFin;
            $paro->duracion_dias = $dias;
            $paro->aplicado = true;
            $paro->ots_afectadas = $afectadas;
            $paro->save();
        });

        return redirect()->route('paros.index')
            ->with('exito', "Paro cerrado. {$afectadas} órdenes desplazadas {$dias} días.");
    }
}
