-- 008_band_locations.sql
-- Table relationnelle N steps × M villes par band pour le géocodage multi-périodes.
-- Remplace la logique mono-entrée de geocode_queue pour les nouveaux traitements.

CREATE TABLE IF NOT EXISTS band_locations (
  id                 BIGSERIAL PRIMARY KEY,
  ma_id              BIGINT NOT NULL REFERENCES bands(ma_id) ON DELETE CASCADE,
  step_order         SMALLINT NOT NULL DEFAULT 0,
  step_label         TEXT,
  location_raw       TEXT NOT NULL,
  is_country_only    BOOLEAN NOT NULL DEFAULT FALSE,
  lat                DOUBLE PRECISION,
  lon                DOUBLE PRECISION,
  geocode_status     TEXT NOT NULL DEFAULT 'queued',
  geocode_query      TEXT,
  geocode_provider   TEXT,
  geocode_confidence REAL,
  geocode_error      TEXT,
  geocode_tries_geo  SMALLINT NOT NULL DEFAULT 0,
  geocode_tries_llm  SMALLINT NOT NULL DEFAULT 0,
  geocode_next_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
  created_at         TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at         TIMESTAMPTZ NOT NULL DEFAULT now(),
  UNIQUE (ma_id, step_order, location_raw)
);

-- Index pour la boucle de travail du geocoder
CREATE INDEX IF NOT EXISTS idx_bl_geo_work
  ON band_locations (geocode_next_at ASC, id ASC)
  WHERE geocode_status = 'queued';

-- Index pour la boucle du groq-worker
CREATE INDEX IF NOT EXISTS idx_bl_llm_work
  ON band_locations (geocode_tries_llm ASC, id ASC)
  WHERE geocode_status = 'llm_needed';

-- Index de navigation par band
CREATE INDEX IF NOT EXISTS idx_bl_ma_id ON band_locations (ma_id);

-- Cache pour éviter de rappeler le LLM pour la même entrée
CREATE TABLE IF NOT EXISTS llm_cache (
  id             BIGSERIAL PRIMARY KEY,
  input_hash     TEXT NOT NULL UNIQUE,
  model          TEXT NOT NULL,
  prompt         TEXT NOT NULL,
  response       TEXT NOT NULL,
  parsed_city    TEXT,
  parsed_country TEXT,
  is_null        BOOLEAN NOT NULL DEFAULT FALSE,
  tokens_in      INTEGER,
  tokens_out     INTEGER,
  cost_usd       NUMERIC(10, 8),
  created_at     TIMESTAMPTZ NOT NULL DEFAULT now()
);
