"""Dolt/SEC fundamentals schema — workstream A

Revision ID: 026
Revises: 025
Create Date: 2026-07-21 00:00:00.000000

Foundational schema for the Dolt bulk-data integration (workstream A): the
batch import-run audit table, the SEC-sourced immutable fundamental snapshots
(CIK-keyed, one row per accession), the Dolt earnings calendar/history, and the
SEC issuer identity columns on ``tickers``. No data is populated here — the
importers land in a later phase. ``fundamental_data`` is left untouched; its
cutover is gated separately (phase A5). ``data_import_runs`` is created first
because the other two tables carry an ``import_run_id`` FK to it.
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


revision: str = "026"
down_revision: Union[str, None] = "025"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    op.create_table(
        "data_import_runs",
        sa.Column("id", sa.Integer(), primary_key=True),
        sa.Column("source", sa.String(length=32), nullable=False),
        sa.Column("revision", sa.String(length=64), nullable=True),
        sa.Column("status", sa.String(length=16), nullable=False),
        sa.Column("source_max_date", sa.Date(), nullable=True),
        sa.Column("row_counts_json", sa.Text(), nullable=True),
        sa.Column("validation_json", sa.Text(), nullable=True),
        sa.Column("started_at", sa.DateTime(timezone=True), nullable=False),
        sa.Column("completed_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("error_details", sa.Text(), nullable=True),
    )
    op.create_index(
        "ix_data_import_runs_source_started", "data_import_runs", ["source", "started_at"]
    )

    op.create_table(
        "fundamental_snapshots",
        sa.Column("id", sa.Integer(), primary_key=True),
        sa.Column("cik", sa.String(length=10), nullable=False),
        sa.Column("accession", sa.String(length=25), nullable=False),
        sa.Column("form", sa.String(length=12), nullable=False),
        sa.Column("filed_date", sa.Date(), nullable=False),
        sa.Column("accepted_at", sa.DateTime(timezone=True), nullable=False),
        sa.Column("period_start", sa.Date(), nullable=True),
        sa.Column("period_end", sa.Date(), nullable=False),
        sa.Column("fiscal_year", sa.Integer(), nullable=False),
        sa.Column("fiscal_period", sa.String(length=4), nullable=False),
        # duration facts — cumulative YTD/FY
        sa.Column("revenue", sa.Float(), nullable=True),
        sa.Column("net_income", sa.Float(), nullable=True),
        sa.Column("operating_income", sa.Float(), nullable=True),
        sa.Column("diluted_eps", sa.Float(), nullable=True),
        sa.Column("cfo", sa.Float(), nullable=True),
        sa.Column("capex", sa.Float(), nullable=True),
        sa.Column("depreciation_amortization", sa.Float(), nullable=True),
        # balance-sheet facts — period-end
        sa.Column("cash_and_st_investments", sa.Float(), nullable=True),
        sa.Column("total_debt", sa.Float(), nullable=True),
        sa.Column("shares_outstanding", sa.Float(), nullable=True),
        sa.Column("shares_outstanding_date", sa.Date(), nullable=True),
        sa.Column(
            "import_run_id",
            sa.Integer(),
            sa.ForeignKey("data_import_runs.id", ondelete="SET NULL"),
            nullable=True,
        ),
        sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
        sa.UniqueConstraint("accession", name="uq_fundamental_snapshots_accession"),
    )
    op.create_index(
        "ix_fundamental_snapshots_cik_period",
        "fundamental_snapshots",
        ["cik", "fiscal_year", "fiscal_period"],
    )
    op.create_index(
        "ix_fundamental_snapshots_cik_period_end",
        "fundamental_snapshots",
        ["cik", "period_end"],
    )

    op.create_table(
        "earnings_events",
        sa.Column("id", sa.Integer(), primary_key=True),
        sa.Column(
            "ticker_id",
            sa.Integer(),
            sa.ForeignKey("tickers.id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column("announce_date", sa.Date(), nullable=False),
        sa.Column("session", sa.String(length=10), nullable=False),
        sa.Column("period_end", sa.Date(), nullable=True),
        sa.Column("eps_estimate", sa.Float(), nullable=True),
        sa.Column("eps_actual", sa.Float(), nullable=True),
        sa.Column("source", sa.String(length=32), nullable=False),
        sa.Column(
            "import_run_id",
            sa.Integer(),
            sa.ForeignKey("data_import_runs.id", ondelete="SET NULL"),
            nullable=True,
        ),
        sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
        sa.UniqueConstraint("ticker_id", "announce_date", name="uq_earnings_ticker_announce"),
    )
    op.create_index(
        "ix_earnings_events_announce_date", "earnings_events", ["announce_date"]
    )

    # SEC issuer identity on tickers (nullable; the only ticker<->issuer join point).
    op.add_column("tickers", sa.Column("cik", sa.String(length=10), nullable=True))
    op.add_column("tickers", sa.Column("sic", sa.String(length=4), nullable=True))
    op.add_column(
        "tickers", sa.Column("sic_description", sa.String(length=160), nullable=True)
    )


def downgrade() -> None:
    op.drop_column("tickers", "sic_description")
    op.drop_column("tickers", "sic")
    op.drop_column("tickers", "cik")

    op.drop_index("ix_earnings_events_announce_date", table_name="earnings_events")
    op.drop_table("earnings_events")

    op.drop_index(
        "ix_fundamental_snapshots_cik_period_end", table_name="fundamental_snapshots"
    )
    op.drop_index(
        "ix_fundamental_snapshots_cik_period", table_name="fundamental_snapshots"
    )
    op.drop_table("fundamental_snapshots")

    op.drop_index(
        "ix_data_import_runs_source_started", table_name="data_import_runs"
    )
    op.drop_table("data_import_runs")
