-- ============================================
-- Vuelato: Sistema de cola de busquedas y seguimiento de precios
-- Tablas: search_cache, tracked_searches, search_runs, price_snapshots
-- ============================================

-- Cache de resultados de busqueda (publica, sin RLS)
-- TTL gestionado por el worker (limpia >2h)

CREATE TABLE IF NOT EXISTS search_cache (
  id SERIAL PRIMARY KEY,
  params_hash TEXT UNIQUE NOT NULL,
  search_params JSONB NOT NULL,
  trips JSONB NOT NULL DEFAULT '[]',
  cheapest_price NUMERIC(10,2),
  total_results INTEGER DEFAULT 0,
  fetched_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_search_cache_hash ON search_cache(params_hash);
CREATE INDEX IF NOT EXISTS idx_search_cache_fetched ON search_cache(fetched_at);

-- Busquedas recurrentes configuradas por el usuario

CREATE TABLE IF NOT EXISTS tracked_searches (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  name TEXT NOT NULL,
  search_params JSONB NOT NULL,
  route_summary TEXT NOT NULL,
  interval_hours INTEGER NOT NULL DEFAULT 24,
  is_active BOOLEAN DEFAULT true,
  next_run_at TIMESTAMPTZ DEFAULT now(),
  last_run_at TIMESTAMPTZ,
  run_count INTEGER DEFAULT 0,
  last_error TEXT,
  expires_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ DEFAULT now()
);

-- Log de cada ejecucion de una busqueda tracked

CREATE TABLE IF NOT EXISTS search_runs (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tracked_search_id UUID NOT NULL REFERENCES tracked_searches(id) ON DELETE CASCADE,
  status TEXT NOT NULL DEFAULT 'pending',
  cheapest_price NUMERIC(10,2),
  total_trips_found INTEGER DEFAULT 0,
  top_trips JSONB,
  from_cache BOOLEAN DEFAULT false,
  error_message TEXT,
  started_at TIMESTAMPTZ,
  completed_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ DEFAULT now()
);

-- Snapshots de precio para graficos

CREATE TABLE IF NOT EXISTS price_snapshots (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tracked_search_id UUID NOT NULL REFERENCES tracked_searches(id) ON DELETE CASCADE,
  search_run_id UUID NOT NULL REFERENCES search_runs(id) ON DELETE CASCADE,
  cheapest_price NUMERIC(10,2) NOT NULL,
  avg_price NUMERIC(10,2),
  median_price NUMERIC(10,2),
  total_results INTEGER DEFAULT 0,
  recorded_at TIMESTAMPTZ DEFAULT now()
);

-- Indices

CREATE INDEX IF NOT EXISTS idx_tracked_searches_user ON tracked_searches(user_id);
CREATE INDEX IF NOT EXISTS idx_tracked_searches_next_run ON tracked_searches(next_run_at) WHERE is_active = true;
CREATE INDEX IF NOT EXISTS idx_search_runs_tracked ON search_runs(tracked_search_id);
CREATE INDEX IF NOT EXISTS idx_price_snapshots_tracked ON price_snapshots(tracked_search_id);
CREATE INDEX IF NOT EXISTS idx_price_snapshots_recorded ON price_snapshots(tracked_search_id, recorded_at);

-- RLS

ALTER TABLE tracked_searches ENABLE ROW LEVEL SECURITY;
ALTER TABLE search_runs ENABLE ROW LEVEL SECURITY;
ALTER TABLE price_snapshots ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Users see own tracked_searches" ON tracked_searches
  FOR ALL USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id);

CREATE POLICY "Users see own search_runs" ON search_runs
  FOR ALL USING (tracked_search_id IN (SELECT id FROM tracked_searches WHERE user_id = auth.uid()))
  WITH CHECK (tracked_search_id IN (SELECT id FROM tracked_searches WHERE user_id = auth.uid()));

CREATE POLICY "Users see own price_snapshots" ON price_snapshots
  FOR ALL USING (tracked_search_id IN (SELECT id FROM tracked_searches WHERE user_id = auth.uid()))
  WITH CHECK (tracked_search_id IN (SELECT id FROM tracked_searches WHERE user_id = auth.uid()));

-- Grants

GRANT SELECT ON search_cache TO anon, authenticated;
GRANT ALL ON search_cache TO service_role;
GRANT USAGE, SELECT ON SEQUENCE search_cache_id_seq TO service_role;

GRANT ALL ON tracked_searches, search_runs, price_snapshots TO authenticated;
GRANT ALL ON tracked_searches, search_runs, price_snapshots TO service_role;
