-- Migration 039: Hype Cycle Analysis table
-- Norton-Bass diffusion model output + Gartner phase classification per technology
--
-- Computed by: packages/scraper/src/utils/hype-cycle-engine.ts
-- Triggered:   compute:hype-cycle job (daily 04:00)

-- Extend market_metrics CHECK constraint to allow asp_decline_rate (already exists) + hype_score
ALTER TABLE market_metrics
  DROP CONSTRAINT IF EXISTS market_metrics_metric_type_check;

ALTER TABLE market_metrics
  ADD CONSTRAINT market_metrics_metric_type_check
  CHECK (metric_type = ANY (ARRAY[
    'vendor_count',
    'shipment_share',
    'asp_decline_rate',
    'media_hype_index',
    'patent_filings',
    'port_shipments',
    'revenue_usd',
    'asp_usd',
    'hype_score'         -- 0-100 composite hype position on Gartner curve
  ]));

-- Norton-Bass fitted parameters + phase classification (one row per technology per run)
CREATE TABLE IF NOT EXISTS hype_cycle_analysis (
  id                  uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  computed_at         timestamptz NOT NULL DEFAULT NOW(),
  technology          text NOT NULL,        -- e.g. '400G-QSFP-DD', '800G-OSFP'
  -- Bass model parameters (fitted)
  bass_p              numeric,              -- coefficient of innovation (0.001–0.03)
  bass_q              numeric,              -- coefficient of imitation (0.1–0.5)
  bass_m              numeric,              -- market potential (0.0–1.0 as share)
  -- Adoption curve metrics
  t_peak_year         numeric,              -- calendar year of peak adoption rate
  current_t           numeric,              -- years since first commercial availability
  current_share       numeric,              -- current shipment share (0–1)
  projected_share_1y  numeric,              -- projected share in 1 year
  projected_share_3y  numeric,              -- projected share in 3 years
  -- Hype Cycle positioning
  hype_phase          text NOT NULL,        -- see CHECK below
  hype_score          numeric,              -- 0-100: position on Gartner curve
  phase_since_year    numeric,              -- calendar year current phase started
  years_to_next_phase numeric,             -- estimated years until next phase
  -- Price trajectory
  asp_current_usd     numeric,              -- current OEM ASP in USD
  asp_decline_pct_3y  numeric,              -- projected ASP decline % over 3 years
  -- Fit quality
  r_squared           numeric,              -- goodness of fit (0–1)
  data_points         integer,              -- number of historical data points used
  notes               text,
  CONSTRAINT hype_cycle_phase_check CHECK (hype_phase = ANY (ARRAY[
    'innovation_trigger',
    'peak_inflated_expectations',
    'trough_disillusionment',
    'slope_enlightenment',
    'plateau_productivity'
  ]))
);

CREATE INDEX IF NOT EXISTS idx_hype_tech_time ON hype_cycle_analysis (technology, computed_at DESC);

-- Keep only the latest 90 days of analysis rows (historical snapshots for trend)
CREATE OR REPLACE FUNCTION cleanup_hype_cycle_analysis() RETURNS void LANGUAGE sql AS $$
  DELETE FROM hype_cycle_analysis WHERE computed_at < NOW() - INTERVAL '90 days';
$$;
