PRAGMA foreign_keys = ON;

CREATE TABLE IF NOT EXISTS ipo_master (
  ticker TEXT PRIMARY KEY,
  company_name_en TEXT NOT NULL,
  company_name_zh TEXT,
  stock_short_name TEXT,
  exchange TEXT NOT NULL DEFAULT 'HKEX',
  board TEXT NOT NULL DEFAULT 'Main Board',
  status TEXT NOT NULL,
  listing_date TEXT,
  application_start_date TEXT,
  application_end_date TEXT,
  allotment_results_expected_date TEXT,
  industry_label TEXT,
  data_as_of TEXT NOT NULL,
  notes TEXT
);

CREATE TABLE IF NOT EXISTS offering_terms (
  ticker TEXT PRIMARY KEY REFERENCES ipo_master(ticker),
  source_id TEXT NOT NULL,
  prospectus_date TEXT,
  offer_price_hkd REAL,
  board_lot INTEGER,
  min_subscription_amount_hkd REAL,
  global_offer_shares INTEGER,
  hk_offer_shares_initial INTEGER,
  international_offer_shares_initial INTEGER,
  public_offer_pct_initial REAL,
  over_allotment_offer_shares INTEGER,
  offer_size_adjustment_offer_shares INTEGER,
  market_cap_hkd_m REAL,
  gross_proceeds_hkd_m REAL,
  net_proceeds_hkd_m REAL,
  issued_shares_upon_listing INTEGER,
  data_as_of TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS ipo_demand (
  demand_id TEXT PRIMARY KEY,
  ticker TEXT NOT NULL REFERENCES ipo_master(ticker),
  source_id TEXT NOT NULL,
  stage_date TEXT NOT NULL,
  valid_applications INTEGER,
  successful_applications INTEGER,
  public_oversubscription_times REAL,
  international_placees INTEGER,
  international_oversubscription_times REAL,
  final_hk_offer_shares INTEGER,
  final_international_offer_shares INTEGER,
  data_as_of TEXT NOT NULL,
  notes TEXT
);

CREATE TABLE IF NOT EXISTS price_performance (
  performance_id TEXT PRIMARY KEY,
  ticker TEXT NOT NULL REFERENCES ipo_master(ticker),
  stage TEXT NOT NULL,
  source_id TEXT,
  as_of_date TEXT NOT NULL,
  open_price_hkd REAL,
  high_price_hkd REAL,
  low_price_hkd REAL,
  close_price_hkd REAL,
  return_pct REAL,
  turnover_hkd_m REAL,
  data_as_of TEXT NOT NULL,
  notes TEXT,
  UNIQUE (ticker, stage)
);

CREATE TABLE IF NOT EXISTS new_listing_report_entries (
  report_entry_id TEXT PRIMARY KEY,
  ticker TEXT NOT NULL REFERENCES ipo_master(ticker),
  report_year INTEGER NOT NULL,
  board TEXT NOT NULL,
  source_id TEXT NOT NULL,
  company_name_en TEXT NOT NULL,
  prospectus_date TEXT,
  listing_date TEXT NOT NULL,
  offer_price_hkd REAL,
  funds_raised_hkd REAL,
  subscription_ratio_times REAL,
  market_cap_hkd REAL,
  outstanding_shares_at_listing INTEGER,
  listing_method TEXT,
  industry_label TEXT,
  place_of_incorporation TEXT,
  sponsors TEXT,
  reporting_accountants TEXT,
  valuers TEXT,
  data_as_of TEXT NOT NULL,
  notes TEXT,
  UNIQUE (ticker, report_year, board)
);

CREATE TABLE IF NOT EXISTS source_refs (
  source_id TEXT PRIMARY KEY,
  ticker TEXT NOT NULL REFERENCES ipo_master(ticker),
  source_type TEXT NOT NULL,
  title TEXT NOT NULL,
  path_base TEXT NOT NULL DEFAULT 'repo_root',
  local_path TEXT NOT NULL,
  url TEXT NOT NULL,
  file_sha256 TEXT,
  source_date TEXT,
  archived_at TEXT NOT NULL,
  notes TEXT,
  CHECK (path_base = 'repo_root'),
  CHECK (local_path NOT LIKE '/%'),
  CHECK (local_path NOT LIKE './%'),
  CHECK (local_path NOT LIKE '%\%')
);

CREATE TABLE IF NOT EXISTS data_gaps (
  gap_id TEXT PRIMARY KEY,
  ticker TEXT NOT NULL REFERENCES ipo_master(ticker),
  stage TEXT NOT NULL,
  field_name TEXT NOT NULL,
  reason TEXT NOT NULL,
  expected_resolution_date TEXT,
  created_at TEXT NOT NULL,
  notes TEXT
);

CREATE TABLE IF NOT EXISTS sync_runs (
  sync_run_id TEXT PRIMARY KEY,
  mode TEXT NOT NULL,
  as_of TEXT NOT NULL,
  started_at TEXT NOT NULL,
  finished_at TEXT,
  status TEXT NOT NULL,
  notes TEXT,
  CHECK (status IN ('running', 'complete', 'failed'))
);

CREATE TABLE IF NOT EXISTS ticker_sync_state (
  ticker TEXT NOT NULL REFERENCES ipo_master(ticker),
  stage TEXT NOT NULL,
  status TEXT NOT NULL,
  required INTEGER NOT NULL DEFAULT 1,
  due_date TEXT,
  completed_at TEXT,
  last_source_id TEXT,
  data_gap_id TEXT,
  last_sync_run_id TEXT REFERENCES sync_runs(sync_run_id),
  updated_at TEXT NOT NULL,
  notes TEXT,
  PRIMARY KEY (ticker, stage),
  CHECK (status IN ('complete', 'pending_not_due', 'pending_due', 'blocked', 'not_applicable')),
  CHECK (required IN (0, 1))
);

CREATE TABLE IF NOT EXISTS sync_tasks (
  task_id TEXT PRIMARY KEY,
  ticker TEXT NOT NULL REFERENCES ipo_master(ticker),
  stage TEXT NOT NULL,
  task_type TEXT NOT NULL,
  task_status TEXT NOT NULL,
  due_date TEXT,
  data_gap_id TEXT,
  last_sync_run_id TEXT REFERENCES sync_runs(sync_run_id),
  updated_at TEXT NOT NULL,
  notes TEXT,
  CHECK (task_status IN ('open', 'waiting_until_due', 'blocked'))
);
