"""SQLAlchemy 2.0 ORM models for the operational store. JSON columns work on both Postgres and SQLite,
so the same models serve production (Postgres) and dev/test (SQLite)."""
from __future__ import annotations

import datetime as dt
from typing import Any

from sqlalchemy import JSON, Boolean, DateTime, Float, Integer, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column


class Base(DeclarativeBase):
    pass


class ResearchRunRow(Base):
    __tablename__ = "research_runs"

    run_id: Mapped[str] = mapped_column(String(64), primary_key=True)
    symbol: Mapped[str] = mapped_column(String(32), index=True)
    asset_class: Mapped[str] = mapped_column(String(16))
    venue: Mapped[str] = mapped_column(String(16))
    currency: Mapped[str] = mapped_column(String(8))
    strategy_kind: Mapped[str] = mapped_column(String(32), index=True)
    params: Mapped[dict[str, Any]] = mapped_column(JSON)
    cagr: Mapped[float] = mapped_column(Float)
    ann_vol: Mapped[float] = mapped_column(Float)
    sharpe: Mapped[float] = mapped_column(Float)
    max_drawdown: Mapped[float] = mapped_column(Float)
    n_obs: Mapped[int] = mapped_column(Integer)
    passed: Mapped[bool] = mapped_column(Boolean, index=True)
    dsr: Mapped[float] = mapped_column(Float)
    is_sharpe: Mapped[float] = mapped_column(Float)
    oos_sharpe: Mapped[float] = mapped_column(Float)
    n_trials: Mapped[int] = mapped_column(Integer)
    reasons: Mapped[list[Any]] = mapped_column(JSON)
    created_at: Mapped[dt.datetime] = mapped_column(DateTime)


# NOTE: StrategyRow/FactoryMetaRow/SeenCandidateRow (tables strategies/factory_meta/seen_candidates) were
# removed 2026-06-25 with the dormant strategy-factory — they were the factory's lifecycle/accounting store,
# unused by any live path. ResearchRunRow above stays (still used by operational.py / research / discover).
