from __future__ import annotations

from sqlite3 import Connection, IntegrityError

from jarvis_finance.audit.log import record_audit_event
from jarvis_finance.imports.common import stable_id, utc_now
from jarvis_finance.quality.alerts import create_alert


def create_crypto_asset(
    conn: Connection,
    *,
    coin_name: str,
    symbol: str,
    coingecko_id: str | None = None,
    network_chain_default: str | None = None,
    is_stablecoin: bool = False,
    notes: str | None = None,
) -> str:
    symbol = symbol.upper().strip()
    existing_symbol = conn.execute("SELECT asset_id FROM crypto_assets WHERE symbol=?", (symbol,)).fetchone()
    asset_id = stable_id("cryptoasset", coingecko_id or coin_name, symbol, network_chain_default or "")
    now = utc_now()
    try:
        conn.execute(
            """
            INSERT INTO crypto_assets(
                asset_id, coin_name, symbol, coingecko_id, network_chain_default,
                is_stablecoin, price_provider_primary, is_active, notes, created_at
            ) VALUES (?, ?, ?, ?, ?, ?, 'CoinGecko', 1, ?, ?)
            """,
            (asset_id, coin_name, symbol, coingecko_id, network_chain_default, int(is_stablecoin), notes, now),
        )
    except IntegrityError as exc:
        raise ValueError("crypto asset uniqueness conflict; coingecko_id must be unique") from exc
    if not coingecko_id:
        create_alert(
            conn,
            priority="warnung",
            category="crypto",
            entity_type="crypto_asset",
            entity_id=asset_id,
            rule_id="missing_coingecko_id",
            message="Crypto asset has no CoinGecko ID; valuation quality is incomplete.",
            evidence={"symbol": symbol, "coin_name": coin_name},
            fingerprint="missing_coingecko_id",
        )
    if existing_symbol:
        create_alert(
            conn,
            priority="warnung",
            category="crypto",
            entity_type="crypto_asset",
            entity_id=asset_id,
            rule_id="crypto_symbol_conflict",
            message="Crypto symbol is not unique; manual asset selection is required.",
            evidence={"symbol": symbol, "existing_asset_id": existing_symbol["asset_id"]},
        )
    record_audit_event(
        conn,
        source="crypto_assets",
        action="create_crypto_asset",
        entity_type="crypto_asset",
        entity_id=asset_id,
        new_values={"coin_name": coin_name, "symbol": symbol, "coingecko_id": coingecko_id},
        confirmed=True,
        created_by="system",
    )
    conn.commit()
    return asset_id


def get_crypto_asset(conn: Connection, asset_id: str):
    row = conn.execute("SELECT * FROM crypto_assets WHERE asset_id=?", (asset_id,)).fetchone()
    if row is None:
        raise KeyError(asset_id)
    return row
