-- Forecasting Pipeline Tables
-- Run once to create the schema. Safe to re-run (IF NOT EXISTS).

-- Precomputed reference decay curves per brand (or brand x category at any hierarchy level)
CREATE TABLE IF NOT EXISTS brand_lifecycle_curves (
    id SERIAL PRIMARY KEY,
    brand TEXT NOT NULL,
    root_category TEXT,                      -- NULL = brand-level fallback curve, else category name
    cat_id BIGINT,                           -- NULL = brand-only; else category_hierarchy.cat_id for precise matching
    category_level SMALLINT,                 -- NULL = brand-only; 0-3 = hierarchy depth
    amplitude NUMERIC(10,4),                 -- A in: sales(t) = A * exp(-λt) + C
    decay_rate NUMERIC(10,6),                -- λ  (higher = faster decay)
    baseline NUMERIC(10,4),                  -- C  (long-tail steady-state daily sales)
    r_squared NUMERIC(6,4),                  -- goodness of fit
    sample_size INT,                         -- number of products that informed this curve
    median_first_week_sales NUMERIC(10,2),   -- for scaling new launches
    median_preorder_sales NUMERIC(10,2),     -- for scaling pre-order products
    median_preorder_days NUMERIC(10,2),      -- median pre-order accumulation window (days)
    computed_at TIMESTAMP DEFAULT NOW(),
    UNIQUE(brand, cat_id)
);

-- Per-product daily forecasts (next 90 days, regenerated each run)
CREATE TABLE IF NOT EXISTS product_forecasts (
    pid BIGINT NOT NULL,
    forecast_date DATE NOT NULL,
    forecast_units NUMERIC(10,2),
    forecast_revenue NUMERIC(14,4),
    lifecycle_phase TEXT,                     -- preorder, launch, decay, mature, slow_mover, dormant
    forecast_method TEXT,                     -- lifecycle_curve, exp_smoothing, velocity, zero
    confidence_lower NUMERIC(10,2),
    confidence_upper NUMERIC(10,2),
    generated_at TIMESTAMP DEFAULT NOW(),
    PRIMARY KEY (pid, forecast_date)
);

CREATE INDEX IF NOT EXISTS idx_pf_date ON product_forecasts(forecast_date);
CREATE INDEX IF NOT EXISTS idx_pf_phase ON product_forecasts(lifecycle_phase);

-- Forecast run history (for monitoring)
CREATE TABLE IF NOT EXISTS forecast_runs (
    id SERIAL PRIMARY KEY,
    started_at TIMESTAMP NOT NULL,
    finished_at TIMESTAMP,
    status TEXT DEFAULT 'running',            -- running, completed, failed
    products_forecast INT,
    phase_counts JSONB,                       -- {"launch": 50, "decay": 200, ...}
    curve_count INT,                          -- brand curves computed
    error_message TEXT,
    duration_seconds NUMERIC(10,2)
);
