<?php
// list_lookup.php

// Turn off display of errors in the response, log instead
ini_set('display_errors', '0');
error_reporting(E_ALL);

//require_once __DIR__ . '/rate_limit.php';

// Convert PHP errors to exceptions so we can return JSON
set_error_handler(function($severity, $message, $file, $line) {
    throw new ErrorException($message, 0, $severity, $file, $line);
});

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

try {
    $raw = file_get_contents('php://input');
    $js = json_decode($raw, true);
    if (!$js || !isset($js['lat'], $js['lng'])) {
        http_response_code(400);
        echo json_encode(['ok' => false, 'error' => 'Missing lat/lng'], JSON_PRETTY_PRINT);
        exit;
    }

    $lat   = (float)$js['lat'];
    $lng   = (float)$js['lng'];
    $debug = !empty($js['debug']);

    // LIST PlanningOnline MapServer
    $service = 'https://services.thelist.tas.gov.au/arcgis/rest/services/Public/PlanningOnline/MapServer';

    /**
     * Query a MapServer layer by a point (lng/lat in EPSG:4326).
     * $returnGeometry: include geometry in the response
     * $extraParams: override/add raw ArcGIS params (e.g. resultRecordCount)
     */
    function arcgis_query($layerId, $lng, $lat, $outFields = '*', $returnGeometry = false, $extraParams = []) {
        global $service;

        $params = array_merge([
            'f'                => 'json',
            'where'            => '1=1',
            'returnGeometry'   => $returnGeometry ? 'true' : 'false',
            'outFields'        => $outFields,
            'outSR'            => '4326', // lat/lng for Leaflet
            'geometryType'     => 'esriGeometryPoint',
            'spatialRel'       => 'esriSpatialRelIntersects',
            'inSR'             => '4326',
            'geometry'         => json_encode(['x' => (float)$lng, 'y' => (float)$lat]),
            // Don't artificially limit multi-hit layers; override per-call below
            'resultRecordCount'=> 100
        ], $extraParams);

        $url = "{$service}/{$layerId}/query";
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => http_build_query($params),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT        => 15,
        ]);
        $resp = curl_exec($ch);
        if ($resp === false) {
            $err = curl_error($ch);
            curl_close($ch);
            return ['error' => "cURL error: $err"];
        }
        curl_close($ch);
        return json_decode($resp, true);
    }

    // Layer IDs on PlanningOnline
    $LAYER_PARCELS = 2;   // Cadastral Parcels
    $LAYER_LGA     = 8;   // Local Government Areas
    $LAYER_ZONES   = 13;  // Tasmanian Planning Scheme Zones
    $LAYER_CODES   = 14;  // Tasmanian Planning Scheme Code Overlays

    // --- Parcels (attributes) ---
    $parcelsResp = arcgis_query($LAYER_PARCELS, $lng, $lat, '*', false, ['resultRecordCount' => 1]);
    $parcelFeat  = $parcelsResp['features'][0] ?? null;
    $parcelAttr  = $parcelFeat['attributes'] ?? [];

    if (!$parcelFeat) {
        echo json_encode(['ok' => false, 'error' => 'No parcel found at that location']);
        exit;
    }

    // PID (field names vary)
    $pid = $parcelAttr['PID'] ?? $parcelAttr['PROPERTY_ID'] ?? null;

    // --- Parcel geometry (polygon) for map ---
    $parcelGeomResp = arcgis_query($LAYER_PARCELS, $lng, $lat, 'PID,OBJECTID', true, ['resultRecordCount' => 1]);

    $boundaryGeoJSON = null;
    if (!empty($parcelGeomResp['features'][0]['geometry']['rings'])) {
        // outSR=4326 → [lng, lat] ready for Leaflet/GeoJSON
        $rings = $parcelGeomResp['features'][0]['geometry']['rings'];
        $boundaryGeoJSON = [
            'type'       => 'Feature',
            'geometry'   => [
                'type'        => 'Polygon',
                'coordinates' => $rings
            ],
            'properties' => [
                'pid' => $pid
            ]
        ];
    }

    // --- Compose Title Id ---
    $volume  = $parcelAttr['VOLUME'] ?? null;
    $folio   = isset($parcelAttr['FOLIO']) ? (string)$parcelAttr['FOLIO'] : null;
    $titleId = null;
    if ($volume && $folio !== null && $folio !== '') {
        $titleId = $volume . '/' . $folio;
    } else {
        $titleId = $parcelAttr['CT'] ?? $parcelAttr['CT_REFERENCE'] ?? null;
    }

    // --- Area ---
    $sqm = null;
    if (isset($parcelAttr['MEAS_AREA'])) {
        $sqm = (float)$parcelAttr['MEAS_AREA'];
    } elseif (isset($parcelAttr['COMP_AREA'])) {
        $sqm = (float)$parcelAttr['COMP_AREA'];
    } elseif (isset($parcelAttr['AREA_SQM'])) {
        $sqm = (float)$parcelAttr['AREA_SQM'];
    }

    $total_area = null;
    $area_sqm_label = null;
    $area_ha_label  = null;
    if ($sqm !== null) {
        $ha = $sqm / 10000.0;
        $area_sqm_label = number_format($sqm, 0) . ' sqm';
        $area_ha_label  = rtrim(rtrim(number_format($ha, 4, '.', ''), '0'), '.') . ' ha';
        $total_area = [
            'sqm'       => (float)$sqm,
            'sqm_label' => $area_sqm_label,
            'ha'        => (float)$ha,
            'ha_label'  => $area_ha_label
        ];
    }

    $tenure   = $parcelAttr['TENURE_TY'] ?? null;
    $lpi      = $parcelAttr['LPI'] ?? null;
    $listGuid = $parcelAttr['LIST_GUID'] ?? null;

    // --- LGA / Council ---
    $lgaResp = arcgis_query($LAYER_LGA, $lng, $lat, '*', false, ['resultRecordCount' => 1]);
    $lgaAttr = $lgaResp['features'][0]['attributes'] ?? [];
    $council = $lgaAttr['LGA_NAME'] ?? $lgaAttr['NAME'] ?? $lgaAttr['COUNCIL'] ?? null;

    // --- Zones (multiple may intersect the point) ---
    $zonesResp    = arcgis_query($LAYER_ZONES, $lng, $lat, '*', false, ['resultRecordCount' => 100]);
    $zoneFeatures = $zonesResp['features'] ?? [];
    $zoneNames    = [];
    $schemeName   = null;

    foreach ($zoneFeatures as $zf) {
        $a = $zf['attributes'] ?? [];
        foreach (['ZONE', 'ZONING', 'ZONE_NAME', 'ZONE_LABEL'] as $k) {
            if (!empty($a[$k])) { $zoneNames[] = $a[$k]; break; }
        }
        if (!$schemeName) {
            $schemeName = $a['LPS'] ?? $a['SCHEME'] ?? 'Tasmanian Planning Scheme';
        }
    }

    // --- Code overlays (multiple) ---
    $codesResp    = arcgis_query($LAYER_CODES, $lng, $lat, '*', false, ['resultRecordCount' => 200]);
    $codeFeatures = $codesResp['features'] ?? [];
    $codeNames    = [];

    foreach ($codeFeatures as $cf) {
        $a = $cf['attributes'] ?? [];
        foreach (['CODE', 'OVERLAY', 'OVERLAY_CODE', 'CODE_NAME', 'OVERLAY_DESC'] as $k) {
            if (!empty($a[$k])) { $codeNames[] = $a[$k]; break; }
        }
    }

    $out = [
        'ok'               => true,
        'pid'              => $pid,
        'title_id'         => $titleId,
        'tenure'           => $tenure,
        'lpi'              => $lpi,
        'list_guid'        => $listGuid,
        'total_area'       => $total_area, // structured with sqm/ha + labels
        'area_sqm'         => $area_sqm_label, // flat labels for your UI
        'area_ha'          => $area_ha_label,
        'council'          => $council,
        'planning_scheme'  => $schemeName,
        'planning_zones'   => array_values(array_unique(array_filter($zoneNames))),
        'planning_codes'   => array_values(array_unique(array_filter($codeNames))),
        'boundary'         => $boundaryGeoJSON
    ];

    if ($debug) {
        $out['debug'] = [
            'parcel_attrs' => $parcelAttr,
            'lga_attrs'    => $lgaAttr,
            'zones_count'  => count($zoneFeatures),
            'codes_count'  => count($codeFeatures)
        ];
    }

    echo json_encode($out, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
} catch (Throwable $e) {
    http_response_code(500);
    echo json_encode(['ok' => false, 'error' => $e->getMessage()]);
}