<?php
// regenerate_lines.php
// Endpoint untuk meregenerasi ap_lines_{safe_ip}.json dari ap_data_{safe_ip}.json
// Pastikan user sudah login (sama seperti peta.php)
session_start();
if (!isset($_SESSION['ip'], $_SESSION['user'], $_SESSION['pass'])) {
    http_response_code(403);
    echo json_encode(['ok'=>false,'error'=>'not_logged_in']);
    exit;
}

header('Content-Type: application/json; charset=utf-8');

$safe_ip = preg_replace('/[^a-zA-Z0-9_\-\.]/', '_', $_SESSION['ip']);
$dataFile = __DIR__ . "/ap_data_{$safe_ip}.json";
$linesFile = __DIR__ . "/ap_lines_{$safe_ip}.json";

if (!file_exists($dataFile)) {
    echo json_encode(['ok'=>false,'error'=>'ap_data_missing']);
    exit;
}

$apList = json_decode(file_get_contents($dataFile), true);
if (!is_array($apList)) $apList = [];

// helper: haversine
function haversine($lat1, $lon1, $lat2, $lon2){
    $R = 6378137;
    $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 $R * $c;
}

// mercator helpers
function toRad($deg){ return $deg * M_PI / 180.0; }
function toDeg($rad){ return $rad * 180.0 / M_PI; }
function latLngToMercator($lat, $lng){
    $R = 6378137;
    $x = $R * toRad($lng);
    $y = $R * log(tan(M_PI/4 + toRad($lat)/2));
    return ['x'=>$x,'y'=>$y];
}
function mercatorToLatLng($x, $y){
    $R = 6378137;
    $lng = toDeg($x / $R);
    $lat = toDeg(2 * atan(exp($y / $R)) - M_PI/2);
    return ['lat'=>$lat,'lng'=>$lng];
}

// quadratic bezier sampling in mercator space
function sampleQuadraticBezier($p0, $p1, $p2, $n){
    $pts = [];
    for($i=0;$i<=$n;$i++){
        $t = $i / $n;
        $u = 1 - $t;
        $x = $u*$u*$p0['x'] + 2*$u*$t*$p1['x'] + $t*$t*$p2['x'];
        $y = $u*$u*$p0['y'] + 2*$u*$t*$p1['y'] + $t*$t*$p2['y'];
        $pts[] = ['x'=>$x,'y'=>$y];
    }
    return $pts;
}

// helper: compute control point (perpendicular offset) similar logic ke client
function computeControlPoint($p1, $p2, $sign=1){
    // p1/p2 mercator points ['x','y']
    $dx = $p2['x'] - $p1['x'];
    $dy = $p2['y'] - $p1['y'];
    $seg = sqrt($dx*$dx + $dy*$dy);
    if ($seg < 0.0001) return ['x'=>($p1['x']+$p2['x'])/2, 'y'=>($p1['y']+$p2['y'])/2];
    // perpendicular
    $nx = -$dy;
    $ny = $dx;
    $norm = sqrt($nx*$nx + $ny*$ny) ?: 1;
    $nx /= $norm; $ny /= $norm;
    // offset proportional and clamped (meters)
    $offset = min(max(8, $seg * 0.055), 140);
    return ['x' => ($p1['x']+$p2['x'])/2 + $nx * $offset * $sign, 'y' => ($p1['y']+$p2['y'])/2 + $ny * $offset * $sign];
}

$apById = [];
foreach($apList as $a) if(!empty($a['id'])) $apById[$a['id']] = $a;

$linesData = [];
foreach($apList as $ap){
    if (empty($ap['line'])) continue;
    $fromRef = $ap['line'];
    $from = null;
    if (isset($apById[$fromRef])) $from = $apById[$fromRef];
    else {
        // fallback: try ip matching
        foreach($apList as $cand) if(!empty($cand['ip']) && $cand['ip']===$fromRef){ $from = $cand; break; }
    }
    if (!$from) continue;

    $lat1 = (float)$from['lat']; $lng1 = (float)$from['lng'];
    $lat2 = (float)$ap['lat'];   $lng2 = (float)$ap['lng'];
    $straight = haversine($lat1,$lng1,$lat2,$lng2);

    // decide number of samples: more for longer lines, but cap to avoid huge JSON
    $N = max(6, min(40, (int)round($straight / 200))); // ~1 sample per 200m, clamped 6..40

    // create mercator points
    $m1 = latLngToMercator($lat1, $lng1);
    $m2 = latLngToMercator($lat2, $lng2);
    // choose sign to alternate curve direction for visual variety via id hash
    $sum = 0; foreach(str_split($ap['id']) as $ch) $sum += ord($ch);
    $sign = ($sum % 2 === 0) ? 1 : -1;
    $ctrl = computeControlPoint($m1, $m2, $sign);

    // sample quadratic bezier
    $mercPts = sampleQuadraticBezier($m1, $ctrl, $m2, $N);
    // convert back to latlng and format [lat,lng]
    $latlngs = array_map(function($pt){ $ll = mercatorToLatLng($pt['x'],$pt['y']); return [ (float)$ll['lat'], (float)$ll['lng'] ]; }, $mercPts);

    // midpoint approximate (middle sample)
    $midIdx = (int)floor(count($latlngs)/2);
    $mid = $latlngs[$midIdx] ?? [ ($lat1+$lat2)/2, ($lng1+$lng2)/2 ];

    $linesData[$ap['id']] = [
        'id' => $ap['id'],
        'fromRef' => $fromRef,
        'toId' => $ap['id'],
        'latlngs' => $latlngs,            // sampled points (many)
        'straight' => $straight,
        'mid' => $mid,
        'color' => $ap['lineColor'] ?? 'lime'
    ];
}

// try write file
if (file_put_contents($linesFile, json_encode($linesData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)) === false) {
    echo json_encode(['ok'=>false,'error'=>'write_failed']);
    exit;
}

echo json_encode(['ok'=>true,'lines_count'=>count($linesData),'file'=>$linesFile]);