<?php

namespace App\Http\Controllers;

use App\Models\OrdenTrabajo;
use App\Models\PlanMantenimiento;
use App\Models\Equipo;
use App\Models\Area;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;

class DashboardController extends Controller
{
    public function index(Request $request)
    {
        $hoy = Carbon::today();
        $inicioMes = $hoy->copy()->startOfMonth();
        $finMes = $hoy->copy()->endOfMonth();

        // Filtros
        $area_id = $request->integer('area_id') ?: null;
        $busqueda = trim((string) $request->get('q', ''));

        $base = OrdenTrabajo::query();
        if ($area_id) $base->where('area_id', $area_id);
        if ($busqueda !== '') $base->where('codigo', 'like', "%{$busqueda}%");

        $total_mes = (clone $base)->whereBetween('fecha_programada', [$inicioMes, $finMes])->count();
        $pendientes = (clone $base)->whereHas('estado', fn($q) => $q->where('codigo', 'PEN'))->count();
        $en_proceso = (clone $base)->whereHas('estado', fn($q) => $q->where('codigo', 'EPR'))->count();
        $ejecutadas = (clone $base)->whereHas('estado', fn($q) => $q->whereIn('codigo', ['EJE','APR']))->count();
        $vencidas = (clone $base)->whereHas('estado', fn($q) => $q->where('codigo', 'VEN'))
            ->orWhere(function($q) use ($hoy) {
                $q->whereNotNull('fecha_programada')
                  ->where('fecha_programada', '<', $hoy)
                  ->whereHas('estado', fn($qq) => $qq->whereIn('codigo', ['PEN','EPR']));
            })->count();
        $reprogramadas = (clone $base)->whereHas('estado', fn($q) => $q->where('codigo', 'REP'))->count();
        $aprobadas = (clone $base)->whereHas('estado', fn($q) => $q->where('codigo', 'APR'))->count();
        $criticas = (clone $base)->whereHas('prioridad', fn($q) => $q->where('codigo', 'CRI'))->count();

        $cumplimiento = $total_mes > 0 ? round(($ejecutadas * 100) / max(1, $total_mes), 1) : 0;
        $costo_mes = (clone $base)->whereBetween('fecha_programada', [$inicioMes, $finMes])->sum('costo_total');

        $kpis = compact('total_mes','pendientes','en_proceso','ejecutadas','vencidas','reprogramadas','aprobadas','criticas','cumplimiento','costo_mes');
        $kpis['planes_activos'] = PlanMantenimiento::where('activo', 1)->count();
        $kpis['equipos_activos'] = Equipo::where('activo', 1)->count();

        // Datos para gráficos (12)
        $g_estados = DB::table('ordenes_trabajo')
            ->leftJoin('estados_orden', 'ordenes_trabajo.estado_id', '=', 'estados_orden.id')
            ->whereBetween('fecha_programada', [$inicioMes, $finMes])
            ->select('estados_orden.nombre', 'estados_orden.color', DB::raw('count(*) as total'))
            ->groupBy('estados_orden.nombre','estados_orden.color')->get();

        $g_areas = DB::table('ordenes_trabajo')
            ->leftJoin('areas','ordenes_trabajo.area_id','=','areas.id')
            ->whereBetween('fecha_programada', [$inicioMes, $finMes])
            ->select('areas.nombre', DB::raw('count(*) as total'), DB::raw('sum(costo_total) as costo'))
            ->groupBy('areas.nombre')->get();

        $g_clase = DB::table('ordenes_trabajo')
            ->whereBetween('fecha_programada', [$inicioMes, $finMes])
            ->select('clase', DB::raw('count(*) as total'))->groupBy('clase')->get();

        $g_diaria = DB::table('ordenes_trabajo')
            ->whereBetween('fecha_programada', [$inicioMes, $finMes])
            ->select(DB::raw('DATE(fecha_programada) as dia'), DB::raw('count(*) as total'))
            ->groupBy('dia')->orderBy('dia')->get();

        $g_costo_area = $g_areas->map(fn($a) => ['nombre' => $a->nombre ?? 'Sin área', 'costo' => (float)($a->costo ?? 0)]);

        $g_responsables = DB::table('ordenes_trabajo')
            ->leftJoin('usuarios','ordenes_trabajo.responsable_id','=','usuarios.id')
            ->whereBetween('fecha_programada', [$inicioMes, $finMes])
            ->select(DB::raw("CONCAT(COALESCE(usuarios.nombres,''),' ',COALESCE(usuarios.apellidos,'')) as nombre"), DB::raw('count(*) as total'))
            ->groupBy('nombre')->orderByDesc('total')->limit(10)->get();

        $g_prioridad = DB::table('ordenes_trabajo')
            ->leftJoin('prioridades','ordenes_trabajo.prioridad_id','=','prioridades.id')
            ->whereBetween('fecha_programada', [$inicioMes, $finMes])
            ->select('prioridades.nombre','prioridades.color', DB::raw('count(*) as total'))
            ->groupBy('prioridades.nombre','prioridades.color')->get();

        $g_equipos = DB::table('ordenes_trabajo')
            ->leftJoin('equipos','ordenes_trabajo.equipo_id','=','equipos.id')
            ->whereBetween('fecha_programada', [$inicioMes, $finMes])
            ->select('equipos.nombre', DB::raw('count(*) as total'))
            ->groupBy('equipos.nombre')->orderByDesc('total')->limit(10)->get();

        $g_mensual = DB::table('ordenes_trabajo')
            ->where('fecha_programada', '>=', $hoy->copy()->subMonths(11)->startOfMonth())
            ->select(DB::raw("DATE_FORMAT(fecha_programada,'%Y-%m') as mes"), DB::raw('count(*) as total'),
                     DB::raw('sum(costo_total) as costo'))
            ->groupBy('mes')->orderBy('mes')->get();

        $g_cumpl_mensual = $g_mensual; // reutilizado para % cumplimiento mensual

        $g_tipo_mtto = DB::table('ordenes_trabajo')
            ->leftJoin('planes_items','ordenes_trabajo.plan_id','=','planes_items.plan_id')
            ->leftJoin('tipos_mantenimiento','planes_items.tipo_mantenimiento_id','=','tipos_mantenimiento.id')
            ->select('tipos_mantenimiento.nombre', DB::raw('count(distinct ordenes_trabajo.id) as total'))
            ->groupBy('tipos_mantenimiento.nombre')->get();

        // Listas
        $proximos = OrdenTrabajo::with(['equipo','estado','prioridad','responsable'])
            ->whereDate('fecha_programada', '>=', $hoy)
            ->whereDate('fecha_programada', '<=', $hoy->copy()->addDays(7))
            ->whereHas('estado', fn($q) => $q->whereIn('codigo', ['PEN','EPR','REP']))
            ->orderBy('fecha_programada')->limit(10)->get();

        $ultimas = OrdenTrabajo::with(['equipo','estado','responsable'])
            ->whereNotNull('fecha_cierre')
            ->orderByDesc('fecha_cierre')->limit(20)->get();

        $pendientes_lista = OrdenTrabajo::with(['equipo','estado','responsable'])
            ->whereHas('estado', fn($q) => $q->whereIn('codigo', ['PEN','EPR']))
            ->orderBy('fecha_programada')->limit(10)->get();

        // Próximas PM por horas: equipos cuyo horómetro está cerca o pasó algún umbral.
        $proximas_pm = [];
        $umbrales = ['ultimo_pm_360' => 360, 'ultimo_pm_720' => 720, 'ultimo_pm_4320' => 4320, 'ultimo_pm_8640' => 8640];
        $equiposConHoro = \App\Models\Equipo::with('area')
            ->where('activo', 1)->where('horometro_actual', '>', 0)->get();
        foreach ($equiposConHoro as $eq) {
            foreach ($umbrales as $col => $umbral) {
                $base = (float) ($eq->$col ?? 0);
                if ($base <= 0) continue;
                $delta = (float) $eq->horometro_actual - $base;
                $restantes = $umbral - $delta;
                if ($restantes > $umbral * 0.15) continue; // solo mostrar dentro del 15% final
                $proximas_pm[] = (object) [
                    'equipo' => $eq, 'pm' => $umbral, 'horometro_actual' => (float) $eq->horometro_actual,
                    'base' => $base, 'restantes' => $restantes,
                    'porcentaje' => min(100, ($delta / $umbral) * 100),
                ];
            }
        }
        usort($proximas_pm, fn($a,$b) => $a->restantes <=> $b->restantes);
        $proximas_pm = array_slice($proximas_pm, 0, 10);

        $areas = Area::where('activo',1)->orderBy('nombre')->get();

        return view('dashboard.index', compact(
            'kpis','g_estados','g_areas','g_clase','g_diaria','g_costo_area','g_responsables',
            'g_prioridad','g_equipos','g_mensual','g_cumpl_mensual','g_tipo_mtto',
            'proximos','ultimas','pendientes_lista','proximas_pm','areas','area_id','busqueda'
        ));
    }
}
