
-- Enable trigram extension for fuzzy search
CREATE EXTENSION IF NOT EXISTS pg_trgm;

-- Table 1: Adresses CTOP complètes
CREATE TABLE public.addresses (
  id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  identifiant_unique_adresse TEXT NOT NULL UNIQUE,
  date_diffusion_version TEXT,
  date_creation TEXT,
  date_modification TEXT,
  date_fin TEXT,
  numero_municipal TEXT,
  numero_municipal_suffixe TEXT,
  numero_unite TEXT,
  type_unite TEXT,
  code_postal TEXT,
  seqodo TEXT,
  generique_odonyme TEXT,
  particule_odonyme TEXT,
  specifique_odonyme TEXT,
  point_cardinal_odonyme TEXT,
  odonyme_recompose_normal TEXT,
  odonyme_recompose_court TEXT,
  odonyme_recompose_long TEXT,
  discriminant_odonyme TEXT,
  odonyme_officiel_ctop TEXT,
  adresse_formatee TEXT,
  qualite_positionnement_geometrique TEXT,
  etat TEXT,
  code_utilisation TEXT,
  categorie TEXT,
  nombre_unite INTEGER,
  numero_lot TEXT,
  matricule_unite_evaluation TEXT,
  nosqnocivq TEXT,
  caracteristique_adresse TEXT,
  code_region_administrative TEXT,
  nom_region_administrative TEXT,
  code_mrc TEXT,
  nom_mrc TEXT,
  code_municipalite TEXT,
  nom_municipalite TEXT,
  nom_municipalite_complet TEXT,
  code_arrondissement TEXT,
  nom_arrondissement TEXT,
  code_communaute_metropolitaine TEXT,
  nom_communaute_metropolitaine TEXT,
  identifiant_reseau_routier TEXT,
  cote_route TEXT,
  longitude DOUBLE PRECISION,
  latitude DOUBLE PRECISION
);

-- Table 2: Disponibilité fibre
CREATE TABLE public.fiber_availability (
  id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  id_placemark TEXT,
  id_appart TEXT,
  uuidadresse TEXT NOT NULL,
  nom TEXT,
  civique TEXT,
  appartement TEXT,
  rue TEXT,
  ville TEXT,
  code_postal TEXT,
  lien_googlemap TEXT,
  zone_tarifaire INTEGER NOT NULL DEFAULT 1,
  max_speed INTEGER NOT NULL DEFAULT 0,
  commentaire TEXT,
  CONSTRAINT fk_fiber_address FOREIGN KEY (uuidadresse) REFERENCES public.addresses(identifiant_unique_adresse)
);

-- Index unique sur uuidadresse pour lookup rapide
CREATE INDEX idx_fiber_uuidadresse ON public.fiber_availability(uuidadresse);

-- Indexes trigram pour recherche fuzzy sur adresses
CREATE INDEX idx_addr_odonyme_normal_trgm ON public.addresses USING GIN (odonyme_recompose_normal gin_trgm_ops);
CREATE INDEX idx_addr_odonyme_court_trgm ON public.addresses USING GIN (odonyme_recompose_court gin_trgm_ops);
CREATE INDEX idx_addr_odonyme_long_trgm ON public.addresses USING GIN (odonyme_recompose_long gin_trgm_ops);
CREATE INDEX idx_addr_formatee_trgm ON public.addresses USING GIN (adresse_formatee gin_trgm_ops);
CREATE INDEX idx_addr_municipalite_trgm ON public.addresses USING GIN (nom_municipalite gin_trgm_ops);
CREATE INDEX idx_addr_code_postal ON public.addresses(code_postal);
CREATE INDEX idx_addr_numero_municipal ON public.addresses(numero_municipal);

-- Fonction de recherche d'adresses avec disponibilité fibre
CREATE OR REPLACE FUNCTION public.search_addresses(
  search_term TEXT,
  result_limit INTEGER DEFAULT 10
)
RETURNS TABLE (
  identifiant_unique_adresse TEXT,
  adresse_formatee TEXT,
  numero_municipal TEXT,
  numero_unite TEXT,
  code_postal TEXT,
  odonyme_recompose_normal TEXT,
  nom_municipalite TEXT,
  longitude DOUBLE PRECISION,
  latitude DOUBLE PRECISION,
  fiber_available BOOLEAN,
  zone_tarifaire INTEGER,
  max_speed INTEGER,
  similarity_score REAL
)
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
BEGIN
  RETURN QUERY
  SELECT
    a.identifiant_unique_adresse,
    a.adresse_formatee,
    a.numero_municipal,
    a.numero_unite,
    a.code_postal,
    a.odonyme_recompose_normal,
    a.nom_municipalite,
    a.longitude,
    a.latitude,
    (f.id IS NOT NULL) AS fiber_available,
    f.zone_tarifaire,
    f.max_speed,
    GREATEST(
      similarity(COALESCE(a.odonyme_recompose_normal, ''), search_term),
      similarity(COALESCE(a.odonyme_recompose_court, ''), search_term),
      similarity(COALESCE(a.odonyme_recompose_long, ''), search_term),
      similarity(COALESCE(a.adresse_formatee, ''), search_term)
    ) AS similarity_score
  FROM public.addresses a
  LEFT JOIN public.fiber_availability f ON f.uuidadresse = a.identifiant_unique_adresse
  WHERE
    a.odonyme_recompose_normal % search_term
    OR a.odonyme_recompose_court % search_term
    OR a.odonyme_recompose_long % search_term
    OR a.adresse_formatee % search_term
  ORDER BY similarity_score DESC
  LIMIT result_limit;
END;
$$;

-- RLS: lecture publique pour l'auto-suggest
ALTER TABLE public.addresses ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Public read access for addresses" ON public.addresses FOR SELECT USING (true);

ALTER TABLE public.fiber_availability ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Public read access for fiber" ON public.fiber_availability FOR SELECT USING (true);
