CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS pgcrypto;

CREATE TABLE IF NOT EXISTS products (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  asin TEXT UNIQUE,
  title TEXT NOT NULL,
  category TEXT,
  description TEXT,
  price NUMERIC(10,2),
  rating NUMERIC(3,2),
  embedding vector(768),
  metadata JSONB DEFAULT '{}',
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX IF NOT EXISTS products_embedding_hnsw
  ON products
  USING hnsw (embedding vector_cosine_ops)
  WITH (m = 16, ef_construction = 64);

CREATE INDEX IF NOT EXISTS products_fts
  ON products
  USING gin (to_tsvector('english', title || ' ' || COALESCE(description, '')));

CREATE INDEX IF NOT EXISTS products_category
  ON products (category);

CREATE TABLE IF NOT EXISTS customers (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name TEXT NOT NULL,
  email TEXT UNIQUE NOT NULL,
  segment TEXT DEFAULT 'standard',
  lifetime_value NUMERIC(12,2) DEFAULT 0,
  embedding vector(768),
  ai_metadata JSONB DEFAULT '{}',
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE TABLE IF NOT EXISTS orders (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  customer_id UUID REFERENCES customers(id),
  amount NUMERIC(10,2),
  status TEXT DEFAULT 'completed',
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX IF NOT EXISTS orders_customer_created_at
  ON orders (customer_id, created_at DESC);

CREATE TABLE IF NOT EXISTS reviews (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  customer_id UUID REFERENCES customers(id),
  product_id UUID REFERENCES products(id),
  text TEXT NOT NULL,
  sentiment_score NUMERIC(4,3),
  embedding vector(768),
  ai_metadata JSONB DEFAULT '{}',
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX IF NOT EXISTS reviews_embedding_hnsw
  ON reviews
  USING hnsw (embedding vector_cosine_ops);

CREATE INDEX IF NOT EXISTS reviews_metadata_gin
  ON reviews USING gin (ai_metadata);

CREATE INDEX IF NOT EXISTS reviews_fts
  ON reviews USING gin (to_tsvector('english', text));

CREATE TABLE IF NOT EXISTS transactions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  customer_id UUID REFERENCES customers(id),
  amount NUMERIC(12,2),
  merchant TEXT,
  location TEXT,
  fraud_score NUMERIC(5,4) DEFAULT 0,
  flagged BOOLEAN DEFAULT false,
  ai_metadata JSONB DEFAULT '{}',
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX IF NOT EXISTS transactions_customer_fraud
  ON transactions (customer_id, fraud_score DESC);

DO $$
BEGIN
  IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'neuralvault_readonly') THEN
    CREATE ROLE neuralvault_readonly LOGIN;
  END IF;
END
$$;

GRANT USAGE ON SCHEMA public TO neuralvault_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO neuralvault_readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO neuralvault_readonly;

-- ── NeuralVault 3.0 Operational & Observability Tracing Schema (Consolidated in Postgres) ──

CREATE TABLE IF NOT EXISTS query_history (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  query_natural TEXT NOT NULL,
  query_sql TEXT,
  execution_success BOOLEAN DEFAULT false,
  row_count INT DEFAULT 0,
  execution_ms NUMERIC(10,2),
  validation_passed BOOLEAN DEFAULT false,
  retry_count INT DEFAULT 0,
  intent_class TEXT,
  indexes_used TEXT[],
  session_id TEXT,
  timestamp NUMERIC(16,4) DEFAULT extract(epoch from now())
);

CREATE TABLE IF NOT EXISTS search_sessions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  query TEXT NOT NULL,
  mode TEXT NOT NULL,
  ef_search INT DEFAULT 40,
  result_count INT DEFAULT 0,
  vector_latency_ms NUMERIC(10,2),
  fts_latency_ms NUMERIC(10,2),
  total_latency_ms NUMERIC(10,2),
  top_result_score NUMERIC(10,4),
  session_id TEXT,
  source TEXT DEFAULT 'postgres',
  timestamp NUMERIC(16,4) DEFAULT extract(epoch from now())
);

CREATE TABLE IF NOT EXISTS query_traces (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  trace_id TEXT NOT NULL UNIQUE,
  query TEXT NOT NULL,
  spans JSONB NOT NULL,
  total_latency_ms NUMERIC(10,2),
  timestamp NUMERIC(16,4) DEFAULT extract(epoch from now())
);

CREATE TABLE IF NOT EXISTS evaluations (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  query TEXT NOT NULL,
  response TEXT,
  metrics JSONB NOT NULL,
  timestamp NUMERIC(16,4) DEFAULT extract(epoch from now())
);

CREATE TABLE IF NOT EXISTS benchmark_history (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  test_runs JSONB NOT NULL,
  timestamp NUMERIC(16,4) DEFAULT extract(epoch from now())
);
