-- Migration: 005_create_facts_table.sql
-- Purpose: Create the fact_timeseries table for Stage 4 aggregation

-- Subject type enum
DO $$ BEGIN
    CREATE TYPE subject_type AS ENUM ('overall', 'urt_code', 'domain', 'issue');
EXCEPTION
    WHEN duplicate_object THEN NULL;
END $$;

-- Bucket type enum
DO $$ BEGIN
    CREATE TYPE bucket_type AS ENUM ('day', 'week', 'month');
EXCEPTION
    WHEN duplicate_object THEN NULL;
END $$;

-- Fact timeseries table
CREATE TABLE IF NOT EXISTS fact_timeseries (
    id BIGSERIAL PRIMARY KEY,

    -- Dimension keys
    business_id VARCHAR(255) NOT NULL,
    place_id VARCHAR(255) NOT NULL,  -- Or 'ALL' for rollup
    period_date DATE NOT NULL,
    bucket_type bucket_type NOT NULL DEFAULT 'day',
    subject_type subject_type NOT NULL DEFAULT 'urt_code',
    subject_id VARCHAR(50) NOT NULL,  -- URT code, domain letter, or issue_id
    taxonomy_version VARCHAR(20) NOT NULL,

    -- Core counts
    review_count INTEGER NOT NULL DEFAULT 0,
    span_count INTEGER NOT NULL DEFAULT 0,

    -- Valence counts
    negative_count INTEGER NOT NULL DEFAULT 0,
    positive_count INTEGER NOT NULL DEFAULT 0,
    neutral_count INTEGER NOT NULL DEFAULT 0,
    mixed_count INTEGER NOT NULL DEFAULT 0,

    -- Strength scores
    strength_score REAL NOT NULL DEFAULT 0.0,
    negative_strength REAL NOT NULL DEFAULT 0.0,
    positive_strength REAL NOT NULL DEFAULT 0.0,

    -- Rating
    avg_rating REAL,

    -- Intensity counts
    i1_count INTEGER NOT NULL DEFAULT 0,
    i2_count INTEGER NOT NULL DEFAULT 0,
    i3_count INTEGER NOT NULL DEFAULT 0,

    -- Comparative counts
    cr_better INTEGER NOT NULL DEFAULT 0,
    cr_worse INTEGER NOT NULL DEFAULT 0,
    cr_same INTEGER NOT NULL DEFAULT 0,

    -- Trust-weighted metrics
    trust_weighted_strength REAL NOT NULL DEFAULT 0.0,
    trust_weighted_negative REAL NOT NULL DEFAULT 0.0,

    -- Metadata
    computed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
    created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),

    -- Unique constraint for upsert
    CONSTRAINT fact_timeseries_unique UNIQUE (
        business_id, place_id, period_date, bucket_type,
        subject_type, subject_id, taxonomy_version
    )
);

-- Indexes for fact_timeseries
CREATE INDEX IF NOT EXISTS idx_facts_business_id ON fact_timeseries(business_id);
CREATE INDEX IF NOT EXISTS idx_facts_place_id ON fact_timeseries(place_id);
CREATE INDEX IF NOT EXISTS idx_facts_period ON fact_timeseries(period_date);
CREATE INDEX IF NOT EXISTS idx_facts_bucket ON fact_timeseries(bucket_type);
CREATE INDEX IF NOT EXISTS idx_facts_subject_type ON fact_timeseries(subject_type);
CREATE INDEX IF NOT EXISTS idx_facts_subject_id ON fact_timeseries(subject_id);

-- Composite index for common dashboard queries
CREATE INDEX IF NOT EXISTS idx_facts_dashboard ON fact_timeseries(
    business_id, place_id, bucket_type, period_date DESC
);

-- Index for specific code trends
CREATE INDEX IF NOT EXISTS idx_facts_code_trend ON fact_timeseries(
    business_id, subject_id, bucket_type, period_date DESC
) WHERE subject_type = 'urt_code';

-- Index for domain aggregates
CREATE INDEX IF NOT EXISTS idx_facts_domain ON fact_timeseries(
    business_id, subject_id, bucket_type, period_date DESC
) WHERE subject_type = 'domain';

COMMENT ON TABLE fact_timeseries IS 'Pre-aggregated time series facts for dashboard queries';
