<?php

namespace App\Http\Controllers;

use App\Models\Area;
use App\Models\Equipo;
use App\Models\Frecuencia;
use App\Models\PlanItem;
use App\Models\PlanMantenimiento;
use App\Models\Sistema;
use App\Models\TipoMantenimiento;
use App\Models\Unidad;
use App\Models\User;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class PlanController extends Controller
{
    public function index(Request $r)
    {
        $clase = $r->get('clase', 'preventivo');
        $q = PlanMantenimiento::with(['area','sistema','equipo'])->withCount('items')->where('clase', $clase);
        if ($busqueda = trim((string) $r->get('q', ''))) {
            $q->where(fn($w) => $w->where('codigo','like',"%$busqueda%")->orWhere('nombre','like',"%$busqueda%"));
        }
        if ($area_id = $r->integer('area_id')) $q->where('area_id', $area_id);
        if ($equipo_id = $r->integer('equipo_id')) $q->where('equipo_id', $equipo_id);
        $registros = $q->orderByDesc('id')->paginate(20)->withQueryString();
        $areas = Area::where('activo',1)->orderBy('nombre')->get();
        return view('planes.index', compact('registros','clase','busqueda','areas','area_id','equipo_id'));
    }

    public function create(Request $r)
    {
        $plan = new PlanMantenimiento(['activo' => true, 'clase' => $r->get('clase', 'preventivo')]);
        return view('planes.form', $this->datosFormulario($plan));
    }

    public function store(Request $r)
    {
        $datos = $this->validar($r);
        $datos['codigo'] = $datos['codigo'] ?: $this->generarCodigo($datos['clase']);
        $datos['creado_por'] = auth()->id();
        $plan = PlanMantenimiento::create($datos);
        return redirect()->route('planes.edit', $plan)->with('exito','Plan creado. Agregue los ítems.');
    }

    public function show(PlanMantenimiento $plan)
    {
        $plan->load(['area','sistema','equipo','items.componente','items.unidad','items.frecuencia','items.tipoMantenimiento','items.responsable']);
        return view('planes.show', compact('plan'));
    }

    public function edit(PlanMantenimiento $plan)
    {
        $plan->load(['items.componente','items.unidad','items.frecuencia','items.tipoMantenimiento','items.responsable']);
        return view('planes.form', $this->datosFormulario($plan));
    }

    public function update(Request $r, PlanMantenimiento $plan)
    {
        $plan->update($this->validar($r, $plan->id));
        return redirect()->route('planes.edit', $plan)->with('exito','Plan actualizado.');
    }

    public function destroy(PlanMantenimiento $plan)
    {
        $plan->delete();
        return redirect()->route('planes.index', ['clase' => $plan->clase])->with('exito','Plan eliminado.');
    }

    public function pdf(PlanMantenimiento $plan)
    {
        $plan->load(['area','sistema','equipo','items.componente','items.unidad','items.frecuencia','items.tipoMantenimiento','items.responsable']);
        $pdf = Pdf::loadView('planes.pdf', ['plan' => $plan])->setPaper('a4', 'landscape');
        return $pdf->stream("plan_{$plan->codigo}.pdf");
    }

    // === Items ===
    public function itemStore(Request $r, PlanMantenimiento $plan)
    {
        $datos = $this->validarItem($r);
        $datos['plan_id'] = $plan->id;
        PlanItem::create($datos);
        return back()->with('exito','Ítem agregado.');
    }

    public function itemUpdate(Request $r, PlanMantenimiento $plan, PlanItem $item)
    {
        abort_unless($item->plan_id === $plan->id, 404);
        $item->update($this->validarItem($r));
        return back()->with('exito','Ítem actualizado.');
    }

    public function itemDestroy(PlanMantenimiento $plan, PlanItem $item)
    {
        abort_unless($item->plan_id === $plan->id, 404);
        $item->delete();
        return back()->with('exito','Ítem eliminado.');
    }

    private function validar(Request $r, ?int $id = null): array
    {
        $datos = $r->validate([
            'codigo' => 'nullable|string|max:30|unique:planes_mantenimiento,codigo' . ($id ? ",$id" : ''),
            'nombre' => 'required|string|max:200',
            'clase' => 'required|in:preventivo,correctivo',
            'area_id' => 'nullable|exists:areas,id',
            'sistema_id' => 'nullable|exists:sistemas,id',
            'equipo_id' => 'nullable|exists:equipos,id',
            'fecha_inicio' => 'nullable|date',
            'fecha_fin' => 'nullable|date|after_or_equal:fecha_inicio',
            'descripcion' => 'nullable|string',
            'observaciones' => 'nullable|string',
            'activo' => 'sometimes|boolean',
        ]);
        $datos['activo'] = $r->boolean('activo');
        return $datos;
    }

    private function validarItem(Request $r): array
    {
        $datos = $r->validate([
            'componente_id' => 'nullable|exists:componentes,id',
            'numero_item' => 'nullable|integer',
            'descripcion' => 'required|string',
            'cambio_lubricacion' => 'nullable|string|max:100',
            'codigo_componente' => 'nullable|string|max:40',
            'unidad_id' => 'nullable|exists:unidades,id',
            'cantidad' => 'nullable|numeric|min:0',
            'frecuencia_id' => 'nullable|exists:frecuencias,id',
            'tipo_mantenimiento_id' => 'nullable|exists:tipos_mantenimiento,id',
            'responsable_id' => 'nullable|exists:usuarios,id',
            'observaciones' => 'nullable|string',
            'costo_estimado' => 'nullable|numeric|min:0',
            'costo_promedio' => 'nullable|numeric|min:0',
            'costo_actual' => 'nullable|numeric|min:0',
        ]);
        foreach (['lila_l_limpieza','lila_i_inspeccion','lila_l_lubricacion','lila_a_ajuste',
                 'pm_360','pm_720','pm_4320','pm_8640','activo'] as $b) {
            $datos[$b] = $r->boolean($b);
        }
        return $datos;
    }

    private function generarCodigo(string $clase): string
    {
        $prefijo = $clase === 'correctivo' ? 'PLANC' : 'PLANP';
        $secuencia = PlanMantenimiento::where('clase',$clase)->where('codigo','like',"$prefijo-%")->count() + 1;
        return $prefijo . '-' . str_pad((string) $secuencia, 4, '0', STR_PAD_LEFT);
    }

    private function datosFormulario(PlanMantenimiento $plan): array
    {
        return [
            'plan' => $plan,
            'areas' => Area::where('activo',1)->orderBy('nombre')->get(),
            'sistemas' => Sistema::where('activo',1)->orderBy('nombre')->get(),
            'equipos' => Equipo::where('activo',1)->orderBy('nombre')->get(),
            'unidades' => Unidad::where('activo',1)->orderBy('nombre')->get(),
            'frecuencias' => Frecuencia::where('activo',1)->orderBy('nombre')->get(),
            'tipos' => TipoMantenimiento::where('activo',1)->orderBy('nombre')->get(),
            'usuarios' => User::where('activo',1)->orderBy('nombres')->get(['id','usuario','nombres','apellidos']),
        ];
    }
}
