-- ══════════════════════════════════════════════════════════════════════════════
-- 118 — Stock Velocity & Sell-Through Analysis
--
-- Evaluates implied Abverkauf (sell-through) from time-series stock_observations:
--   • Negative stock delta → implied units sold (sell event)
--   • Positive stock delta after backorder → Zulauf (incoming replenishment)
--   • FS.com units_sold counter delta → high-confidence sell signal
--
-- Stores per-product velocity results in stock_velocity for API / dashboard use.
-- ══════════════════════════════════════════════════════════════════════════════

-- ── Main results table ────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS stock_velocity (
  id                      UUID        DEFAULT gen_random_uuid() PRIMARY KEY,
  transceiver_id          UUID        NOT NULL REFERENCES transceivers(id) ON DELETE CASCADE,
  vendor_id               UUID        NOT NULL REFERENCES vendors(id) ON DELETE CASCADE,
  computed_at             TIMESTAMPTZ DEFAULT NOW() NOT NULL,

  -- Observation window
  window_start            TIMESTAMPTZ NOT NULL,
  window_end              TIMESTAMPTZ NOT NULL,
  obs_count               INTEGER     NOT NULL,

  -- Sell-through metrics
  avg_daily_sell_rate     NUMERIC(12, 2),   -- units/day (implied)
  peak_daily_sell_rate    NUMERIC(12, 2),   -- highest single-interval rate
  total_sell_events       INTEGER DEFAULT 0,
  total_units_sold_implied INTEGER DEFAULT 0,

  -- FS.com direct counter (more reliable when available)
  units_sold_counter_delta BIGINT,          -- delta in FS.com units_sold between first/last obs
  units_sold_daily_rate   NUMERIC(12, 2),   -- counter_delta / window_days

  -- Zulauf (incoming stock / replenishment)
  total_zulauf_events     INTEGER DEFAULT 0,
  total_units_zulauf      INTEGER DEFAULT 0,
  last_zulauf_at          TIMESTAMPTZ,
  next_expected_delivery  DATE,             -- backorder_estimated_date from latest obs

  -- Current stock state (from latest observation)
  current_qty             INTEGER,
  current_backorder_qty   INTEGER,
  current_price_net       NUMERIC(10, 2),

  -- Sell-through prediction
  estimated_stockout_days NUMERIC(8, 1),    -- NULL if no velocity or stock = 0
  estimated_stockout_date DATE,

  -- Signal quality
  velocity_confidence     TEXT CHECK (velocity_confidence IN ('high', 'medium', 'low', 'insufficient')),
  -- high   = ≥14 observations with meaningful deltas
  -- medium = ≥5 observations
  -- low    = 2–4 observations
  -- insufficient = only 1 observation or no change detected

  UNIQUE (transceiver_id, vendor_id)
);

CREATE INDEX IF NOT EXISTS idx_stock_velocity_vendor     ON stock_velocity (vendor_id);
CREATE INDEX IF NOT EXISTS idx_stock_velocity_computed   ON stock_velocity (computed_at);
CREATE INDEX IF NOT EXISTS idx_stock_velocity_stockout   ON stock_velocity (estimated_stockout_date)
  WHERE estimated_stockout_date IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_stock_velocity_confidence ON stock_velocity (velocity_confidence);

COMMENT ON TABLE stock_velocity IS
  'Computed sell-through velocity per transceiver per vendor, derived from '
  'time-series stock_observations. Refreshed by analyze:stock:velocity job.';

-- ── Sell event log (raw events for trend analysis) ────────────────────────────
CREATE TABLE IF NOT EXISTS stock_velocity_events (
  id                UUID        DEFAULT gen_random_uuid() PRIMARY KEY,
  transceiver_id    UUID        NOT NULL REFERENCES transceivers(id) ON DELETE CASCADE,
  vendor_id         UUID        NOT NULL REFERENCES vendors(id) ON DELETE CASCADE,
  event_at          TIMESTAMPTZ NOT NULL,
  event_type        TEXT        NOT NULL CHECK (event_type IN ('sold', 'zulauf', 'unchanged', 'data_gap')),
  units_delta       INTEGER,    -- negative = sold, positive = arrived
  daily_rate        NUMERIC(10, 2),  -- implied rate for this interval
  qty_before        INTEGER,
  qty_after         INTEGER,
  hours_elapsed     NUMERIC(8, 2)
);

CREATE INDEX IF NOT EXISTS idx_velocity_events_tx  ON stock_velocity_events (transceiver_id, vendor_id, event_at);
CREATE INDEX IF NOT EXISTS idx_velocity_events_type ON stock_velocity_events (event_type, event_at);
