<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class GpsTracking extends Model
{
    /**
     * Tabla asociada
     */
    protected $table = 'gps_tracking';

    /**
     * Clave primaria
     */
    protected $primaryKey = 'tracking_id';

    /**
     * Sin timestamps automáticos
     */
    public $timestamps = false;

    /**
     * Campos asignables
     */
    protected $fillable = [
        'usuario_id',
        'prog_id',
        'latitud',
        'longitud',
        'precision_metros',
        'altitud',
        'velocidad',
        'bateria_porcentaje',
        'fecha_captura',
    ];

    /**
     * Casting de atributos
     */
    protected function casts(): array
    {
        return [
            'latitud' => 'decimal:8',
            'longitud' => 'decimal:8',
            'precision_metros' => 'decimal:2',
            'altitud' => 'decimal:2',
            'velocidad' => 'decimal:2',
            'bateria_porcentaje' => 'integer',
            'fecha_captura' => 'datetime',
            'fecha_registro' => 'datetime',
        ];
    }

    /**
     * Relación con Usuario
     */
    public function usuario()
    {
        return $this->belongsTo(Usuario::class, 'usuario_id', 'usu_id');
    }

    /**
     * Relación con Programación
     */
    public function programacion()
    {
        return $this->belongsTo(MantProgramacion::class, 'prog_id', 'prog_id');
    }

    /**
     * Scope por usuario
     */
    public function scopePorUsuario($query, int $usuarioId)
    {
        return $query->where('usuario_id', $usuarioId);
    }

    /**
     * Scope por programación
     */
    public function scopePorProgramacion($query, int $progId)
    {
        return $query->where('prog_id', $progId);
    }

    /**
     * Scope últimos minutos
     */
    public function scopeUltimosMinutos($query, int $minutos)
    {
        return $query->where('fecha_captura', '>=', now()->subMinutes($minutos));
    }

    /**
     * Scope del día
     */
    public function scopeDelDia($query, ?string $fecha = null)
    {
        $fecha = $fecha ?? now()->toDateString();
        return $query->whereDate('fecha_captura', $fecha);
    }

    /**
     * Scope última posición por usuario
     */
    public function scopeUltimaPosicion($query)
    {
        return $query->orderBy('fecha_captura', 'desc');
    }

    /**
     * Obtener coordenadas como array
     */
    public function getCoordenadasAttribute(): array
    {
        return [
            'lat' => (float) $this->latitud,
            'lng' => (float) $this->longitud,
            'precision' => $this->precision_metros,
            'altitud' => $this->altitud,
            'velocidad' => $this->velocidad,
        ];
    }

    /**
     * Obtener minutos desde última actualización
     */
    public function getMinutosDesdeActualizacionAttribute(): int
    {
        return $this->fecha_captura->diffInMinutes(now());
    }

    /**
     * Verificar si la posición es reciente (< 30 min)
     */
    public function esReciente(): bool
    {
        return $this->minutos_desde_actualizacion < 30;
    }

    /**
     * Verificar si batería está baja (< 20%)
     */
    public function bateriaBaja(): bool
    {
        return $this->bateria_porcentaje !== null && $this->bateria_porcentaje < 20;
    }

    /**
     * Calcular distancia a otro punto (en metros)
     */
    public function distanciaA(float $lat, float $lng): float
    {
        $R = 6371000; // Radio de la Tierra en metros

        $lat1 = deg2rad($this->latitud);
        $lat2 = deg2rad($lat);
        $deltaLat = deg2rad($lat - $this->latitud);
        $deltaLng = deg2rad($lng - $this->longitud);

        $a = sin($deltaLat / 2) * sin($deltaLat / 2) +
            cos($lat1) * cos($lat2) *
            sin($deltaLng / 2) * sin($deltaLng / 2);

        $c = 2 * atan2(sqrt($a), sqrt(1 - $a));

        return $R * $c;
    }
}
