-- normalize_service_locations.sql — « rendre conformes » les adresses de service ERPNext via la base
-- LOCALE rqa_addresses (Adresses Québec), sans détruire l'adresse originale (table de translation embarquée).
--
-- Pour chaque Service Location : on cherche la correspondance RQA par CODE POSTAL + NUMÉRO (clé sélective,
-- indexée), on choisit la meilleure rue par similarité désaccentuée, puis on remplit :
--   aq_address_id = rqa_addresses.id (clé de translation locale)   [⚠ id LOCAL, pas l'uuid AQ officiel]
--   linked_address = adresse canonique conforme (address_full)
--   address_validation_status = validated (sim≥0.20) | review (0<sim<0.20) | unmatched (aucun match)
--   latitude/longitude RAFFINÉES seulement si validated ; address_line/city/postal_code INCHANGÉS (origine préservée)
-- Idempotent : ne traite que les lignes encore 'pending' (re-run sûr). Les 2 tables sont colocalisées
-- dans la db ERPNext _eb65bdc0c4b1b2d6 → tout se fait en SQL (pas d'aller-retour applicatif).
\timing on
BEGIN;

-- Passe 1 : CODE POSTAL + NUMÉRO (forte) — couvre ~97 %.
UPDATE "tabService Location" sl SET
  aq_address_id = m.id,
  linked_address = m.address_full,
  latitude  = CASE WHEN m.sim >= 0.20 THEN m.lat ELSE sl.latitude  END,
  longitude = CASE WHEN m.sim >= 0.20 THEN m.lon ELSE sl.longitude END,
  address_validation_status = CASE WHEN m.sim >= 0.20 THEN 'validated' ELSE 'review' END,
  address_validated_at = NOW(),
  modified = NOW()
FROM (
  SELECT s.name, m.id, m.address_full, m.lat, m.lon, m.sim
  FROM "tabService Location" s
  CROSS JOIN LATERAL (
    SELECT a.id::text AS id, a.address_full, a.latitude AS lat, a.longitude AS lon,
           similarity(a.search_text, lower(unaccent(s.address_line))) AS sim
    FROM rqa_addresses a
    WHERE a.code_postal = replace(upper(coalesce(s.postal_code,'')), ' ', '')
      AND a.numero = (regexp_match(s.address_line, '^\s*(\d+)'))[1]
    ORDER BY similarity(a.search_text, lower(unaccent(s.address_line))) DESC
    LIMIT 1
  ) m
  WHERE s.address_validation_status = 'pending'
    AND s.address_line NOT IN ('', 'N/A', 'xxx')
) m
WHERE m.name = sl.name;

-- Passe 2 : reste non résolu → 'unmatched' (pas de correspondance code postal+numéro).
UPDATE "tabService Location"
SET address_validation_status = 'unmatched', address_validated_at = NOW(), modified = NOW()
WHERE address_validation_status = 'pending';

-- Rapport
SELECT address_validation_status AS statut, count(*) AS n,
       count(NULLIF(aq_address_id,'')) AS avec_lien_aq
FROM "tabService Location" GROUP BY 1 ORDER BY 2 DESC;

COMMIT;
