<?php

namespace App\Services\Geocoding;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class Geocoder
{
    protected string $baseUrl = 'https://maps.googleapis.com/maps/api/geocode/json';

    public function geocode(string $address): ?array
    {
        $key = 'geocode:'.sha1(mb_strtolower(trim($address)));

        return Cache::remember($key, now()->addDays(7), function () use ($address) {

            $apiKey = config('services.google.maps_api_key');

            if (empty($apiKey) || Str::startsWith($apiKey, 'xxxxxxx')) {
                Log::error('Geocoding API Key missing or invalid in configuration.', ['address' => $address]);

                return null;
            }

            try {
                $response = Http::retry(3, 200)
                    ->acceptJson()
                    ->get($this->baseUrl, [
                        'address' => $address,
                        'key' => $apiKey,
                        'region' => 'co',
                    ]);

                if (! $response->successful()) {
                    Log::warning('Geocoding HTTP error', [
                        'address' => $address,
                        'status' => $response->status(),
                        'body' => $response->body(),
                    ]);

                    return null;
                }

                $json = $response->json();

                if (($json['status'] ?? '') !== 'OK' || empty($json['results'][0]['geometry']['location'])) {
                    // Si el status es ZERO_RESULTS (cero resultados), devuelve null.
                    return null;
                }

                $loc = $json['results'][0]['geometry']['location'];

                if (isset($loc['lat'], $loc['lng'])) {
                    return [
                        'lat' => (float) $loc['lat'],
                        'lng' => (float) $loc['lng'],
                    ];
                }

                return null;
            } catch (\Throwable $e) {
                Log::error('Geocoding exception (Connection/Guzzle)', [
                    'address' => $address,
                    'exception' => $e->getMessage(),
                ]);

                return null;
            }
        });
    }
}
