<?php

namespace App\Models\Fish;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class StaticFeaturesGrid extends Model
{
    protected $table = 'static_features_grid';

    protected $fillable = [
        'grid_x', 'grid_y', 'lat', 'lon',
        'depth_m', 'substrate_type', 'bottom_slope',
        'distance_to_coastline_m', 'distance_to_river_mouth_m',
        'distance_to_posidonia_edge_m', 'distance_to_rocky_structure_m',
        'distance_to_artificial_reef_m', 'distance_to_wreck_m',
        'water_column_zone', 'exposure', 'estuarine_influence',
        'protected_area_distance_m',
    ];

    protected $casts = [
        'lat' => 'decimal:7',
        'lon' => 'decimal:7',
        'depth_m' => 'decimal:2',
        'distance_to_coastline_m' => 'decimal:1',
        'distance_to_river_mouth_m' => 'decimal:1',
        'distance_to_posidonia_edge_m' => 'decimal:1',
        'distance_to_rocky_structure_m' => 'decimal:1',
        'distance_to_artificial_reef_m' => 'decimal:1',
        'distance_to_wreck_m' => 'decimal:1',
        'estuarine_influence' => 'decimal:2',
        'protected_area_distance_m' => 'decimal:1',
    ];

    public function habitatScores(): HasMany
    {
        return $this->hasMany(StaticHabitatScore::class, 'grid_id');
    }

    /**
     * Verilen koordinata en yakın grid hücresini bulur.
     */
    public static function findNearest(float $lat, float $lon): ?self
    {
        return static::query()
            ->selectRaw('*, (
                6371000 * acos(
                    cos(radians(?)) * cos(radians(lat)) *
                    cos(radians(lon) - radians(?)) +
                    sin(radians(?)) * sin(radians(lat))
                )
            ) as distance', [$lat, $lon, $lat])
            ->orderBy('distance')
            ->first();
    }

    /**
     * Verilen bbox içindeki grid hücrelerini döndürür.
     */
    public static function withinBbox(float $minLat, float $minLon, float $maxLat, float $maxLon)
    {
        return static::query()
            ->whereBetween('lat', [$minLat, $maxLat])
            ->whereBetween('lon', [$minLon, $maxLon]);
    }
}
