BEGIN;

ALTER TABLE app_user ADD COLUMN IF NOT EXISTS is_admin boolean NOT NULL DEFAULT false;
CREATE INDEX IF NOT EXISTS idx_app_user_is_admin ON app_user (is_admin);

CREATE INDEX IF NOT EXISTS idx_strategy_run_user_status ON strategy_run (user_id, status);
CREATE INDEX IF NOT EXISTS idx_strategy_run_user_created ON strategy_run (user_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_engine_event_user_run_ts ON engine_event (user_id, run_id, ts DESC);
CREATE INDEX IF NOT EXISTS idx_strategy_log_user_run_ts ON strategy_log (user_id, run_id, ts DESC);
CREATE INDEX IF NOT EXISTS idx_event_ledger_user_run_logical ON event_ledger (user_id, run_id, logical_time);
CREATE INDEX IF NOT EXISTS idx_paper_order_user_run_ts ON paper_order (user_id, run_id, "timestamp" DESC);
CREATE INDEX IF NOT EXISTS idx_paper_trade_user_run_ts ON paper_trade (user_id, run_id, "timestamp" DESC);
CREATE INDEX IF NOT EXISTS idx_mtm_ledger_user_run_ts ON mtm_ledger (user_id, run_id, "timestamp" DESC);
CREATE INDEX IF NOT EXISTS idx_paper_equity_curve_user_run_ts ON paper_equity_curve (user_id, run_id, "timestamp" DESC);
CREATE INDEX IF NOT EXISTS idx_engine_status_user_run ON engine_status (user_id, run_id);
CREATE INDEX IF NOT EXISTS idx_engine_state_paper_user_run ON engine_state_paper (user_id, run_id);

CREATE OR REPLACE VIEW admin_user_metrics AS
WITH session_stats AS (
  SELECT
    user_id,
    MIN(created_at) AS first_session_at,
    MAX(COALESCE(last_seen_at, created_at)) AS last_login_at
  FROM app_session
  GROUP BY user_id
),
run_stats AS (
  SELECT
    user_id,
    COUNT(*) AS runs_count,
    MAX(CASE WHEN status = 'RUNNING' THEN run_id END) AS active_run_id,
    MAX(CASE WHEN status = 'RUNNING' THEN status END) AS active_run_status,
    MIN(created_at) AS first_run_at
  FROM strategy_run
  GROUP BY user_id
),
broker_stats AS (
  SELECT user_id, BOOL_OR(connected) AS broker_connected
  FROM user_broker
  GROUP BY user_id
)
SELECT
  u.id AS user_id,
  u.username,
  u.is_admin,
  COALESCE(session_stats.first_session_at, run_stats.first_run_at) AS created_at,
  session_stats.last_login_at,
  COALESCE(run_stats.runs_count, 0) AS runs_count,
  run_stats.active_run_id,
  run_stats.active_run_status,
  COALESCE(broker_stats.broker_connected, FALSE) AS broker_connected
FROM app_user u
LEFT JOIN session_stats ON session_stats.user_id = u.id
LEFT JOIN run_stats ON run_stats.user_id = u.id
LEFT JOIN broker_stats ON broker_stats.user_id = u.id;

CREATE OR REPLACE VIEW admin_run_metrics AS
WITH order_stats AS (
  SELECT user_id, run_id, COUNT(*) AS order_count, MAX("timestamp") AS last_order_time
  FROM paper_order
  GROUP BY user_id, run_id
),
trade_stats AS (
  SELECT user_id, run_id, COUNT(*) AS trade_count, MAX("timestamp") AS last_trade_time
  FROM paper_trade
  GROUP BY user_id, run_id
),
event_stats AS (
  SELECT
    user_id,
    run_id,
    MAX("timestamp") AS last_event_time,
    MAX(CASE WHEN event = 'SIP_EXECUTED' THEN "timestamp" END) AS last_sip_time
  FROM event_ledger
  GROUP BY user_id, run_id
),
equity_latest AS (
  SELECT DISTINCT ON (user_id, run_id)
    user_id,
    run_id,
    equity AS equity_latest,
    pnl AS pnl_latest,
    "timestamp" AS equity_ts
  FROM paper_equity_curve
  ORDER BY user_id, run_id, "timestamp" DESC
),
mtm_latest AS (
  SELECT DISTINCT ON (user_id, run_id)
    user_id,
    run_id,
    "timestamp" AS mtm_ts
  FROM mtm_ledger
  ORDER BY user_id, run_id, "timestamp" DESC
),
log_latest AS (
  SELECT user_id, run_id, MAX(ts) AS last_log_time
  FROM strategy_log
  GROUP BY user_id, run_id
),
engine_latest AS (
  SELECT user_id, run_id, MAX(ts) AS last_engine_time
  FROM engine_event
  GROUP BY user_id, run_id
),
activity AS (
  SELECT user_id, run_id, MAX(ts) AS last_event_time
  FROM (
    SELECT user_id, run_id, ts FROM engine_event
    UNION ALL
    SELECT user_id, run_id, ts FROM strategy_log
    UNION ALL
    SELECT user_id, run_id, "timestamp" AS ts FROM paper_order
    UNION ALL
    SELECT user_id, run_id, "timestamp" AS ts FROM paper_trade
    UNION ALL
    SELECT user_id, run_id, "timestamp" AS ts FROM mtm_ledger
    UNION ALL
    SELECT user_id, run_id, "timestamp" AS ts FROM paper_equity_curve
    UNION ALL
    SELECT user_id, run_id, "timestamp" AS ts FROM event_ledger
  ) t
  GROUP BY user_id, run_id
)
SELECT
  sr.run_id,
  sr.user_id,
  sr.status,
  sr.created_at,
  sr.started_at,
  sr.stopped_at,
  sr.strategy,
  sr.mode,
  sr.broker,
  sc.sip_amount,
  sc.sip_frequency_value,
  sc.sip_frequency_unit,
  sc.next_run AS next_sip_time,
  activity.last_event_time,
  event_stats.last_sip_time,
  COALESCE(order_stats.order_count, 0) AS order_count,
  COALESCE(trade_stats.trade_count, 0) AS trade_count,
  equity_latest.equity_latest,
  equity_latest.pnl_latest
FROM strategy_run sr
LEFT JOIN strategy_config sc
  ON sc.user_id = sr.user_id AND sc.run_id = sr.run_id
LEFT JOIN order_stats
  ON order_stats.user_id = sr.user_id AND order_stats.run_id = sr.run_id
LEFT JOIN trade_stats
  ON trade_stats.user_id = sr.user_id AND trade_stats.run_id = sr.run_id
LEFT JOIN event_stats
  ON event_stats.user_id = sr.user_id AND event_stats.run_id = sr.run_id
LEFT JOIN equity_latest
  ON equity_latest.user_id = sr.user_id AND equity_latest.run_id = sr.run_id
LEFT JOIN mtm_latest
  ON mtm_latest.user_id = sr.user_id AND mtm_latest.run_id = sr.run_id
LEFT JOIN log_latest
  ON log_latest.user_id = sr.user_id AND log_latest.run_id = sr.run_id
LEFT JOIN engine_latest
  ON engine_latest.user_id = sr.user_id AND engine_latest.run_id = sr.run_id
LEFT JOIN activity
  ON activity.user_id = sr.user_id AND activity.run_id = sr.run_id;

CREATE OR REPLACE VIEW admin_engine_health AS
WITH activity AS (
  SELECT user_id, run_id, MAX(ts) AS last_event_time
  FROM (
    SELECT user_id, run_id, ts FROM engine_event
    UNION ALL
    SELECT user_id, run_id, ts FROM strategy_log
    UNION ALL
    SELECT user_id, run_id, "timestamp" AS ts FROM event_ledger
  ) t
  GROUP BY user_id, run_id
)
SELECT
  sr.run_id,
  sr.user_id,
  sr.status,
  activity.last_event_time,
  es.status AS engine_status,
  es.last_updated AS engine_status_ts
FROM strategy_run sr
LEFT JOIN activity
  ON activity.user_id = sr.user_id AND activity.run_id = sr.run_id
LEFT JOIN engine_status es
  ON es.user_id = sr.user_id AND es.run_id = sr.run_id;

CREATE OR REPLACE VIEW admin_order_stats AS
SELECT
  user_id,
  run_id,
  COUNT(*) AS total_orders,
  COUNT(*) FILTER (WHERE "timestamp" >= now() - interval '24 hours') AS orders_last_24h,
  COUNT(*) FILTER (WHERE status = 'FILLED') AS filled_orders
FROM paper_order
GROUP BY user_id, run_id;

CREATE OR REPLACE VIEW admin_ledger_stats AS
WITH mtm_latest AS (
  SELECT DISTINCT ON (user_id, run_id)
    user_id,
    run_id,
    portfolio_value,
    pnl,
    "timestamp" AS mtm_ts
  FROM mtm_ledger
  ORDER BY user_id, run_id, "timestamp" DESC
),
equity_latest AS (
  SELECT DISTINCT ON (user_id, run_id)
    user_id,
    run_id,
    equity,
    pnl,
    "timestamp" AS equity_ts
  FROM paper_equity_curve
  ORDER BY user_id, run_id, "timestamp" DESC
)
SELECT
  sr.user_id,
  sr.run_id,
  mtm_latest.portfolio_value AS mtm_value,
  mtm_latest.pnl AS mtm_pnl,
  mtm_latest.mtm_ts,
  equity_latest.equity AS equity_value,
  equity_latest.pnl AS equity_pnl,
  equity_latest.equity_ts
FROM strategy_run sr
LEFT JOIN mtm_latest
  ON mtm_latest.user_id = sr.user_id AND mtm_latest.run_id = sr.run_id
LEFT JOIN equity_latest
  ON equity_latest.user_id = sr.user_id AND equity_latest.run_id = sr.run_id;

COMMIT;
