<?php
/**
 * ajax/geocodificar.php
 * Proxy de geocodificação e busca de CEP.
 *
 * Ações:
 *   ?acao=cep&cep=01310100              → ViaCEP → retorna logradouro, bairro, cidade
 *   ?acao=cep_por_rua&cidade=X&rua=Y    → ViaCEP busca por rua → retorna cep
 *   ?acao=geocode&rua=X&num=Y&...       → Nominatim → retorna lat, lng, cep, bairro
 *   ?acao=reverse&lat=X&lng=Y           → Nominatim reverso → retorna endereço completo
 */
require_once __DIR__ . '/../auth.php';
require_once __DIR__ . '/../functions.php';
requireLogin();

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

$acao    = $_GET['acao'] ?? 'geocode';
$timeout = 8;

// ── Helper: HTTP GET com file_get_contents ────────────────────────
function httpGet(string $url, int $timeout = 8): ?string {
    $ctx = stream_context_create([
        'http' => [
            'method'  => 'GET',
            'header'  => "User-Agent: MKTTelecom/2.6\r\nAccept: application/json\r\n",
            'timeout' => $timeout,
            'ignore_errors' => true,
        ],
        'ssl' => [
            'verify_peer'      => false,
            'verify_peer_name' => false,
        ],
    ]);
    $res = @file_get_contents($url, false, $ctx);
    return $res === false ? null : $res;
}

// ── Formata CEP: 00000-000 ────────────────────────────────────────
function fmtCep(string $cep): string {
    $c = preg_replace('/\D/', '', $cep);
    if (strlen($c) === 8) return substr($c, 0, 5) . '-' . substr($c, 5);
    return $cep;
}

// ═══════════════════════════════════════════════════════════════════
//  AÇÃO: cep — ViaCEP → endereço completo
// ═══════════════════════════════════════════════════════════════════
if ($acao === 'cep') {
    $cep = preg_replace('/\D/', '', $_GET['cep'] ?? '');
    if (strlen($cep) !== 8) {
        echo json_encode(['ok' => false, 'erro' => 'CEP inválido']);
        exit;
    }

    $res = httpGet("https://viacep.com.br/ws/{$cep}/json/", $timeout);
    if (!$res) {
        echo json_encode(['ok' => false, 'erro' => 'Serviço ViaCEP indisponível']);
        exit;
    }

    $d = json_decode($res, true) ?? [];
    if (!empty($d['erro'])) {
        echo json_encode(['ok' => false, 'erro' => 'CEP não encontrado']);
        exit;
    }

    echo json_encode([
        'ok'         => true,
        'cep'        => fmtCep($d['cep'] ?? $cep),
        'logradouro' => $d['logradouro'] ?? '',
        'bairro'     => $d['bairro']     ?? '',
        'cidade'     => $d['localidade'] ?? '',
        'uf'         => $d['uf']         ?? '',
        'ibge'       => $d['ibge']       ?? '',
    ]);
    exit;
}

// ═══════════════════════════════════════════════════════════════════
//  AÇÃO: cep_por_rua — ViaCEP busca por rua
// ═══════════════════════════════════════════════════════════════════
if ($acao === 'cep_por_rua') {
    $cidade = trim($_GET['cidade'] ?? '');
    $rua    = trim($_GET['rua']    ?? '');
    $uf     = trim($_GET['uf']     ?? 'SP');

    if (!$cidade || !$rua) {
        echo json_encode(['ok' => false, 'erro' => 'Cidade e rua são obrigatórios']);
        exit;
    }

    $url = sprintf(
        'https://viacep.com.br/ws/%s/%s/%s/json/',
        urlencode($uf),
        urlencode($cidade),
        urlencode($rua)
    );

    $res = httpGet($url, $timeout);
    if (!$res) {
        echo json_encode(['ok' => false, 'erro' => 'Serviço ViaCEP indisponível']);
        exit;
    }

    $lista = json_decode($res, true) ?? [];
    if (!is_array($lista) || empty($lista)) {
        echo json_encode(['ok' => false, 'erro' => 'Nenhum resultado encontrado']);
        exit;
    }

    $primeiro = $lista[0];
    echo json_encode([
        'ok'         => true,
        'cep'        => fmtCep($primeiro['cep'] ?? ''),
        'logradouro' => $primeiro['logradouro'] ?? '',
        'bairro'     => $primeiro['bairro']     ?? '',
        'cidade'     => $primeiro['localidade'] ?? '',
    ]);
    exit;
}

// ═══════════════════════════════════════════════════════════════════
//  AÇÃO: geocode — Nominatim → lat/lng
// ═══════════════════════════════════════════════════════════════════
if ($acao === 'geocode') {
    $rua    = trim($_GET['rua']    ?? '');
    $num    = trim($_GET['num']    ?? '');
    $bairro = trim($_GET['bairro'] ?? '');
    $cidade = trim($_GET['cidade'] ?? '');

    if (!$rua || !$cidade) {
        echo json_encode(['ok' => false, 'erro' => 'Rua e cidade são obrigatórios']);
        exit;
    }

    $partes = array_filter([$num ? "$rua, $num" : $rua, $bairro, $cidade, 'SP', 'Brasil']);
    $query  = implode(', ', $partes);

    $url = 'https://nominatim.openstreetmap.org/search?' . http_build_query([
        'q'              => $query,
        'format'         => 'json',
        'limit'          => 1,
        'addressdetails' => 1,
        'countrycodes'   => 'br',
    ]);

    $res = httpGet($url, $timeout);
    if (!$res) {
        echo json_encode(['ok' => false, 'erro' => 'Serviço de geocodificação indisponível']);
        exit;
    }

    $lista = json_decode($res, true) ?? [];
    if (empty($lista)) {
        if ($num) {
            $partes2 = array_filter([$rua, $bairro, $cidade, 'SP', 'Brasil']);
            $query2  = implode(', ', $partes2);
            $url2 = 'https://nominatim.openstreetmap.org/search?' . http_build_query([
                'q'              => $query2,
                'format'         => 'json',
                'limit'          => 1,
                'addressdetails' => 1,
                'countrycodes'   => 'br',
            ]);
            $res2  = httpGet($url2, $timeout);
            $lista = $res2 ? (json_decode($res2, true) ?? []) : [];
        }

        if (empty($lista)) {
            echo json_encode(['ok' => false, 'erro' => 'Endereço não encontrado. Verifique rua e cidade.']);
            exit;
        }
    }

    $r    = $lista[0];
    $addr = $r['address'] ?? [];

    $cepRaw = $addr['postcode'] ?? '';
    $cep    = $cepRaw ? fmtCep(preg_replace('/\D/', '', $cepRaw)) : '';

    $bairroRes = $addr['suburb']       ??
                 $addr['neighbourhood']??
                 $addr['city_district'] ??
                 $addr['quarter']       ?? '';

    echo json_encode([
        'ok'     => true,
        'lat'    => (float)$r['lat'],
        'lng'    => (float)$r['lon'],
        'cep'    => $cep,
        'bairro' => $bairroRes,
        'label'  => $r['display_name'] ?? $query,
    ]);
    exit;
}

// ═══════════════════════════════════════════════════════════════════
//  AÇÃO: reverse — lat/lng → endereço completo
// ═══════════════════════════════════════════════════════════════════
if ($acao === 'reverse') {
    $lat = (float)($_GET['lat'] ?? 0);
    $lng = (float)($_GET['lng'] ?? 0);

    if (!$lat || !$lng) {
        echo json_encode(['ok' => false, 'erro' => 'Coordenadas inválidas']);
        exit;
    }

    $url = 'https://nominatim.openstreetmap.org/reverse?' . http_build_query([
        'lat'             => $lat,
        'lon'             => $lng,
        'format'          => 'json',
        'addressdetails'  => 1,
        'zoom'            => 18,
        'accept-language' => 'pt-BR',
    ]);

    $res = httpGet($url, $timeout);
    if (!$res) {
        $url2 = "https://nominatim.openstreetmap.org/reverse?format=json&lat={$lat}&lon={$lng}";
        $res  = httpGet($url2, $timeout);
    }

    if (!$res) {
        echo json_encode([
            'ok'         => true,
            'lat'        => $lat,
            'lng'        => $lng,
            'cep'        => '',
            'logradouro' => '',
            'numero'     => '',
            'bairro'     => '',
            'cidade'     => '',
            'label'      => "{$lat}, {$lng}",
        ]);
        exit;
    }

    $d    = json_decode($res, true) ?? [];
    $addr = $d['address'] ?? [];

    $cepRaw = $addr['postcode'] ?? '';
    $cep    = $cepRaw ? fmtCep(preg_replace('/\D/', '', $cepRaw)) : '';

    $logradouro = $addr['road']        ??
                  $addr['pedestrian']  ??
                  $addr['path']        ??
                  $addr['footway']     ?? '';

    $numero = $addr['house_number'] ?? '';

    $bairro = $addr['suburb']        ??
              $addr['neighbourhood'] ??
              $addr['city_district'] ??
              $addr['quarter']       ??
              $addr['residential']   ?? '';

    $cidade = $addr['city']         ??
              $addr['town']         ??
              $addr['village']      ??
              $addr['municipality'] ??
              $addr['county']       ?? '';

    echo json_encode([
        'ok'         => true,
        'lat'        => $lat,
        'lng'        => $lng,
        'cep'        => $cep,
        'logradouro' => $logradouro,
        'numero'     => $numero,
        'bairro'     => $bairro,
        'cidade'     => $cidade,
        'label'      => $d['display_name'] ?? '',
    ]);
    exit;
}

echo json_encode(['ok' => false, 'erro' => 'Ação inválida. Use: cep, cep_por_rua, geocode, reverse']);