<?php
// api/risk_score.php

/**
 * Calculates a risk score for a given latitude and longitude.
 *
 * The risk score is based on:
 * 1. Proximity to active wildfires.
 * 2. Location within an active hurricane's forecast cone.
 * 3. Historical hurricane activity in the area.
 */

header('Content-Type: application/json');
ini_set('display_errors', 0); // Don't show errors to the user

require_once __DIR__ . '/../db/config.php';

// --- Utility Functions ---

/**
 * Point in Polygon check.
 * Ray-casting algorithm.
 * @param array $point The point to check: [$lon, $lat]
 * @param array $polygon The polygon vertices: [[$lon, $lat], [$lon, $lat], ...]
 * @return bool True if the point is in the polygon.
 */
function pointInPolygon($point, $polygon) {
    $inside = false;
    $x = $point[0];
    $y = $point[1];
    
    for ($i = 0, $j = count($polygon) - 1; $i < count($polygon); $j = $i++) {
        $xi = $polygon[$i][0];
        $yi = $polygon[$i][1];
        $xj = $polygon[$j][0];
        $yj = $polygon[$j][1];
        
        $intersect = (($yi > $y) != ($yj > $y))
            && ($x < ($xj - $xi) * ($y - $yi) / ($yj - $yi) + $xi);
        if ($intersect) {
            $inside = !$inside;
        }
    }
    
    return $inside;
}

/**
 * Haversine formula for distance between two points on a sphere.
 * @param float $lat1
 * @param float $lon1
 * @param float $lat2
 * @param float $lon2
 * @return float Distance in kilometers.
 */
function haversineDistance($lat1, $lon1, $lat2, $lon2) {
    $earthRadius = 6371; // km
    
    $dLat = deg2rad($lat2 - $lat1);
    $dLon = deg2rad($lon2 - $lon1);
    
    $a = sin($dLat / 2) * sin($dLat / 2) +
         cos(deg2rad($lat1)) * cos(deg2rad($lat2)) *
         sin($dLon / 2) * sin($dLon / 2);
    
    $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
    
    return $earthRadius * $c;
}


// --- Risk Calculation Functions ---

function getWildfireRisk($lat, $lon) {
    $wildfireUrl = 'https://services3.arcgis.com/T4QMspbfLg3qTGWY/arcgis/rest/services/WFIGS_Interagency_Fire_Perimeters_Current/FeatureServer/0/query?where=1%3D1&outFields=poly_IncidentName,poly_GISAcres,attr_InitialLatitude,attr_InitialLongitude&outSR=4326&f=json';
    
    $context = stream_context_create(['http' => ['timeout' => 10]]);
    $wildfireDataJson = @file_get_contents($wildfireUrl, false, $context);
    if (!$wildfireDataJson) {
        return ['score' => 0, 'details' => 'Could not fetch wildfire data.'];
    }
    $wildfireData = json_decode($wildfireDataJson, true);

    if (!$wildfireData || empty($wildfireData['features'])) {
        return ['score' => 0, 'details' => 'No active wildfires found.'];
    }
    
    $risk = 0;
    $closest_distance = PHP_INT_MAX;
    $closest_fire = null;

    foreach ($wildfireData['features'] as $fire) {
        $fireLat = $fire['attributes']['attr_InitialLatitude'];
        $fireLon = $fire['attributes']['attr_InitialLongitude'];
        
        if ($fireLat && $fireLon) {
            $distance = haversineDistance($lat, $lon, $fireLat, $fireLon);
            if ($distance < $closest_distance) {
                $closest_distance = $distance;
                $closest_fire = $fire['attributes']['poly_IncidentName'];
            }
        }
    }

    if ($closest_distance < 50) { // 50km threshold
        $risk = 100 - ($closest_distance / 50) * 100;
    }

    return [
        'score' => round($risk), 
        'details' => $closest_fire ? "Closest fire: {$closest_fire} (" . round($closest_distance) . " km away)" : "No fires within 50km."
    ];
}

function getHurricaneRisk($lat, $lon) {
    // Construct the URL to the local hurricanes API
    $localApiUrl = 'http://localhost/api/hurricanes.php';

    $context = stream_context_create(['http' => ['timeout' => 15]]);
    $geoJsonData = @file_get_contents($localApiUrl, false, $context);

    if (!$geoJsonData) {
        return ['score' => 0, 'details' => 'Could not fetch local hurricane data.'];
    }

    $hurricaneData = json_decode($geoJsonData, true);

    if (!$hurricaneData || empty($hurricaneData['features'])) {
        return ['score' => 0, 'details' => 'No active hurricane data found.'];
    }

    $risk = 0;
    $details = [];
    $point = [(float)$lon, (float)$lat];

    foreach ($hurricaneData['features'] as $feature) {
        // We are only interested in the forecast cone polygons
        if (isset($feature['properties']['layer']) && $feature['properties']['layer'] === 'cone' && $feature['geometry']['type'] === 'Polygon') {
            $polygon = $feature['geometry']['coordinates'][0];
            if (pointInPolygon($point, $polygon)) {
                $risk = 100; // Max risk if inside the cone
                $stormName = $feature['properties']['STORMNAME'] ?? 'Unnamed Storm';
                $details[] = "Inside the forecast cone for " . $stormName;
                break; // Exit after finding the first cone
            }
        }
    }

    return [
        'score' => $risk,
        'details' => !empty($details) ? implode(', ', $details) : 'Not in any active hurricane forecast cones.'
    ];
}

function getHistoricalHurricaneRisk($lat, $lon) {
    $pdo = db();
    if (!$pdo) {
        return ['score' => 0, 'details' => 'Database connection failed.'];
    }

    // Search for storms within a 1-degree radius (~111 km)
    $radius = 1.0; 
    $stmt = $pdo->prepare(
        "SELECT COUNT(DISTINCT storm_id) as storm_count FROM hurricanes WHERE ABS(lat - :lat) < :radius AND ABS(lon - :lon) < :radius"
    );
    $stmt->execute(['lat' => $lat, 'lon' => $lon, 'radius' => $radius]);
    $result = $stmt->fetch(PDO::FETCH_ASSOC);

    $count = $result['storm_count'] ?? 0;
    
    // Simple scoring: 10 points per storm, max 100
    $score = min($count * 10, 100);

    return [
        'score' => $score,
        'details' => "{$count} historical storms passed within ~111km."
    ];
}


// --- Main Execution ---

$lat = $_GET['lat'] ?? null;
$lon = $_GET['lon'] ?? null;

if (!$lat || !$lon) {
    http_response_code(400);
    echo json_encode(['error' => 'Latitude and longitude are required.']);
    exit;
}

$wildfireRisk = getWildfireRisk((float)$lat, (float)$lon);
$hurricaneRisk = getHurricaneRisk((float)$lat, (float)$lon);
$historicalRisk = getHistoricalHurricaneRisk((float)$lat, (float)$lon);

// Weighted average for the total score
$totalScore = ($wildfireRisk['score'] * 0.4) + ($hurricaneRisk['score'] * 0.4) + ($historicalRisk['score'] * 0.2);

$response = [
    'latitude' => (float)$lat,
    'longitude' => (float)$lon,
    'risk_score' => round($totalScore),
    'factors' => [
        'wildfire' => $wildfireRisk,
        'live_hurricane' => $hurricaneRisk,
        'historical_hurricane' => $historicalRisk,
    ]
];

echo json_encode($response, JSON_PRETTY_PRINT);
