import axios from 'axios';
import { Notify } from 'quasar';

const GEOCODING_URL = 'https://maps.googleapis.com/maps/api/geocode/json';

// ── DEBUG via notificação ─────────────────────────────────────────
const dbg = (title, data = {}) => {
  const lines = Object.entries(data).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join('\n');
  Notify.create({ color: 'teal-9', textColor: 'white', position: 'top', message: `[GEO] ${title}`, caption: lines || undefined, timeout: 8000, multiLine: true });
};
// ─────────────────────────────────────────────────────────────────

const parseAddressComponents = (components) => {
  const get = (type, nameType = 'long_name') =>
    components.find((c) => c.types.includes(type))?.[nameType] ?? '';

  return {
    address: `${get('route')}`.trim(),
    number: get('street_number'),
    district: get('sublocality_level_1') || get('sublocality') || get('neighborhood'),
    city: get('administrative_area_level_2'),
    state: get('administrative_area_level_1', 'short_name'),
    zip_code: get('postal_code').replace(/\D/g, ''),
  };
};

const geocodeViaGoogleMaps = async (request) => {
  const geocoder = new window.google.maps.Geocoder();
  const { results } = await geocoder.geocode(request);
  return results ?? [];
};

export const useGeocodingApi = () => {
  const geocodeCep = async (cep) => {
    const cleaned = cep.replace(/\D/g, '');
    const apiKey = process.env.GOOGLE_MAPS_API_KEY;
    const usandoGeocoderNativo = !!window.google?.maps?.Geocoder;

    dbg('geocodeCep', { cep: cleaned, via: usandoGeocoderNativo ? 'Geocoder nativo' : 'HTTP', apiKey: apiKey ? `${apiKey.substring(0, 8)}...` : 'UNDEFINED' });

    if (usandoGeocoderNativo) {
      const results = await geocodeViaGoogleMaps({ address: `${cleaned}, Brazil` });
      dbg('geocodeCep nativo result', { total: results.length, encontrou: results.length > 0 });
      if (!results.length) return null;
      const result = results[0];
      const parsed = parseAddressComponents(result.address_components);
      return {
        lat: result.geometry.location.lat(),
        lng: result.geometry.location.lng(),
        ...parsed,
      };
    }

    const { data } = await axios.get(GEOCODING_URL, {
      params: { address: `${cleaned}, Brazil`, key: apiKey },
    });
    dbg('geocodeCep HTTP result', { status: data.status, total: data.results?.length ?? 0 });
    if (data.status !== 'OK' || !data.results.length) return null;
    const result = data.results[0];
    const { lat, lng } = result.geometry.location;
    return { lat, lng, ...parseAddressComponents(result.address_components) };
  };

  const reverseGeocode = async (lat, lng) => {
    const apiKey = process.env.GOOGLE_MAPS_API_KEY;
    const usandoGeocoderNativo = !!window.google?.maps?.Geocoder;

    dbg('reverseGeocode chamado', { lat, lng, via: usandoGeocoderNativo ? 'Geocoder nativo' : 'HTTP', apiKey: apiKey ? `${apiKey.substring(0, 8)}...` : 'UNDEFINED' });

    if (usandoGeocoderNativo) {
      const results = await geocodeViaGoogleMaps({ location: { lat, lng } });
      dbg('reverseGeocode nativo result', { total: results.length });
      if (!results.length) return null;
      return { lat, lng, ...parseAddressComponents(results[0].address_components) };
    }

    const { data } = await axios.get(GEOCODING_URL, {
      params: { latlng: `${lat},${lng}`, key: apiKey },
    });
    dbg('reverseGeocode HTTP result', { status: data.status, total: data.results?.length ?? 0, errorMessage: data.error_message ?? null });
    if (data.status !== 'OK' || !data.results.length) return null;
    const result = data.results[0];
    return { lat, lng, ...parseAddressComponents(result.address_components) };
  };

  const geocodeFullAddress = async ({ address, number, district, zip_code, city, state }) => {
    const parts = [address, number, district, zip_code, city, state, 'Brazil'].filter(Boolean);
    const query = parts.join(', ');
    const apiKey = process.env.GOOGLE_MAPS_API_KEY;
    const usandoGeocoderNativo = !!window.google?.maps?.Geocoder;

    dbg('geocodeFullAddress', { query, via: usandoGeocoderNativo ? 'Geocoder nativo' : 'HTTP', apiKey: apiKey ? `${apiKey.substring(0, 8)}...` : 'UNDEFINED' });

    if (usandoGeocoderNativo) {
      const results = await geocodeViaGoogleMaps({ address: query });
      dbg('geocodeFullAddress nativo result', { total: results.length });
      if (!results.length) return null;
      const result = results[0];
      return {
        lat: result.geometry.location.lat(),
        lng: result.geometry.location.lng(),
        ...parseAddressComponents(result.address_components),
      };
    }

    const { data } = await axios.get(GEOCODING_URL, {
      params: { address: query, key: apiKey },
    });
    dbg('geocodeFullAddress HTTP result', { status: data.status, total: data.results?.length ?? 0, errorMessage: data.error_message ?? null });
    if (data.status !== 'OK' || !data.results.length) return null;
    const result = data.results[0];
    const { lat, lng } = result.geometry.location;
    return { lat, lng, ...parseAddressComponents(result.address_components) };
  };

  return { geocodeCep, reverseGeocode, geocodeFullAddress };
};
