"""SQLite table definitions for the paper trading system."""
from __future__ import annotations

import sqlite3
from pathlib import Path

SCHEMA_SQL = """
CREATE TABLE IF NOT EXISTS sessions (
    session_id   TEXT PRIMARY KEY,
    session_name TEXT NOT NULL,
    config_path  TEXT NOT NULL,
    initial_equity REAL NOT NULL,
    created_at   TEXT NOT NULL,
    status       TEXT NOT NULL DEFAULT 'active',
    parking_preset TEXT,
    idle_alpha_preset TEXT,
    form4_sleeve_preset TEXT,
    ownership_sleeve_preset TEXT,
    risk_off_alpha_sleeve_preset TEXT
);

CREATE TABLE IF NOT EXISTS strategy_states (
    id             INTEGER PRIMARY KEY AUTOINCREMENT,
    session_id     TEXT NOT NULL REFERENCES sessions(session_id),
    symbol         TEXT NOT NULL,
    event_id       TEXT NOT NULL,
    engine_id      TEXT NOT NULL DEFAULT 'default',
    order_id       TEXT,
    entry_date     TEXT NOT NULL,
    stop_price     REAL NOT NULL,
    target_price   REAL NOT NULL,
    current_stop   REAL NOT NULL,
    peak_price     REAL NOT NULL,
    days_held      INTEGER NOT NULL DEFAULT 0,
    trade_direction TEXT NOT NULL DEFAULT 'long',
    candidate_json TEXT NOT NULL,
    plan_json      TEXT NOT NULL,
    status         TEXT NOT NULL DEFAULT 'open',
    UNIQUE(session_id, symbol, status)
);

CREATE TABLE IF NOT EXISTS session_state (
    session_id          TEXT PRIMARY KEY REFERENCES sessions(session_id),
    consecutive_losses  INTEGER NOT NULL DEFAULT 0,
    cooldown_remaining  INTEGER NOT NULL DEFAULT 0,
    kill_switch_triggered INTEGER NOT NULL DEFAULT 0,
    daily_new_risk_used REAL NOT NULL DEFAULT 0.0,
    last_processed_date TEXT
);

CREATE TABLE IF NOT EXISTS processed_events (
    session_id     TEXT NOT NULL,
    event_id       TEXT NOT NULL,
    processed_date TEXT NOT NULL,
    action         TEXT NOT NULL,
    skip_reason    TEXT,
    PRIMARY KEY (session_id, event_id)
);

CREATE TABLE IF NOT EXISTS trades (
    trade_id     TEXT PRIMARY KEY,
    session_id   TEXT NOT NULL,
    symbol       TEXT NOT NULL,
    engine_id    TEXT,
    capital_bucket_id TEXT,
    entry_date   TEXT,
    exit_date    TEXT,
    entry_price  REAL,
    exit_price   REAL,
    exit_reason  TEXT,
    shares       INTEGER,
    net_pnl      REAL,
    r_multiple   REAL,
    holding_days INTEGER
);

CREATE TABLE IF NOT EXISTS daily_snapshots (
    session_id          TEXT NOT NULL,
    date                TEXT NOT NULL,
    equity              REAL NOT NULL,
    cash                REAL NOT NULL,
    market_value        REAL NOT NULL,
    daily_pnl           REAL,
    total_pnl           REAL,
    drawdown_pct        REAL,
    open_position_count INTEGER,
    PRIMARY KEY (session_id, date)
);

CREATE TABLE IF NOT EXISTS processed_dates (
    session_id TEXT NOT NULL,
    date       TEXT NOT NULL,
    PRIMARY KEY (session_id, date)
);

CREATE TABLE IF NOT EXISTS processed_phases (
    session_id TEXT NOT NULL,
    date       TEXT NOT NULL,
    phase      TEXT NOT NULL,
    PRIMARY KEY (session_id, date, phase)
);

CREATE TABLE IF NOT EXISTS parking_state (
    session_id        TEXT PRIMARY KEY REFERENCES sessions(session_id),
    symbol            TEXT NOT NULL,
    entry_date        TEXT NOT NULL,
    qty               INTEGER NOT NULL,
    avg_price         REAL NOT NULL,
    entry_value       REAL NOT NULL,
    status            TEXT NOT NULL DEFAULT 'active',
    peak_price        REAL NOT NULL DEFAULT 0,
    gate_in_sgov      INTEGER NOT NULL DEFAULT 0,
    committed_target  TEXT NOT NULL DEFAULT '',
    pending_target    TEXT NOT NULL DEFAULT '',
    pending_days      INTEGER NOT NULL DEFAULT 0,
    sgov_entry_value           REAL NOT NULL DEFAULT 0,
    sold_today                 INTEGER NOT NULL DEFAULT 0,
    overlay_brake_cooldown     INTEGER NOT NULL DEFAULT 0,
    overlay_hold_days          INTEGER NOT NULL DEFAULT 0
);
"""


def create_schema(db_path: str | Path) -> None:
    """Initialize the SQLite database with the paper trading schema."""
    conn = sqlite3.connect(str(db_path))
    try:
        conn.executescript(SCHEMA_SQL)
        # Migration: add parking_preset column to existing databases
        try:
            conn.execute("ALTER TABLE sessions ADD COLUMN parking_preset TEXT")
            conn.commit()
        except Exception:
            pass  # column already exists
        try:
            conn.execute("ALTER TABLE sessions ADD COLUMN idle_alpha_preset TEXT")
            conn.commit()
        except Exception:
            pass  # column already exists
        try:
            conn.execute("ALTER TABLE sessions ADD COLUMN form4_sleeve_preset TEXT")
            conn.commit()
        except Exception:
            pass  # column already exists
        try:
            conn.execute("ALTER TABLE sessions ADD COLUMN ownership_sleeve_preset TEXT")
            conn.commit()
        except Exception:
            pass  # column already exists
        try:
            conn.execute("ALTER TABLE sessions ADD COLUMN risk_off_alpha_sleeve_preset TEXT")
            conn.commit()
        except Exception:
            pass  # column already exists
        # Migration: add parking_state columns for v2 (top-up, hysteresis, etc.)
        for col, dtype, default in [
            ("peak_price", "REAL", "0"),
            ("gate_in_sgov", "INTEGER", "0"),
            ("committed_target", "TEXT", "''"),
            ("pending_target", "TEXT", "''"),
            ("pending_days", "INTEGER", "0"),
            ("sgov_entry_value", "REAL", "0"),
            ("sold_today", "INTEGER", "0"),
            ("overlay_brake_cooldown", "INTEGER", "0"),
            ("overlay_hold_days", "INTEGER", "0"),
        ]:
            try:
                conn.execute(f"ALTER TABLE parking_state ADD COLUMN {col} {dtype} NOT NULL DEFAULT {default}")
                conn.commit()
            except Exception:
                pass
        for col, dtype in [
            ("engine_id", "TEXT"),
            ("capital_bucket_id", "TEXT"),
        ]:
            try:
                conn.execute(f"ALTER TABLE trades ADD COLUMN {col} {dtype}")
                conn.commit()
            except Exception:
                pass
    finally:
        conn.close()
