"""eth-labels.db source - 115K EVM labels from local SQLite.

Schema (verified):
  accounts(id, chain_id, address, label, name_tag, created_at, updated_at)

chain_id mapping:
  1 = ethereum, 42161 = arbitrum, 137 = polygon, etc.
"""
from __future__ import annotations

import asyncio
import logging
from datetime import UTC, datetime

from app.domains.labels.models import Label, LabelSource

log = logging.getLogger(__name__)

DB_PATH = "/home/dev/rmi/eth-labels.db"

# chain_id -> chain name mapping (from EVM chains list)
_CHAIN_ID_MAP = {
    1: "ethereum",
    42161: "arbitrum",
    10: "optimism",
    137: "polygon",
    56: "bsc",
    43114: "avalanche",
    250: "fantom",
    100: "gnosis",
}


async def query_eth_labels_db(address: str, chain: str = "ethereum") -> list[Label]:
    """Query the local eth-labels.db SQLite for an address.

    Args:
        address: EVM address (0x...)
        chain: Chain name (only EVM chains in this DB)

    Returns:
        List of labels found (one per chain_id that has a match).
    """
    def _query() -> list[Label]:
        import sqlite3

        try:
            conn = sqlite3.connect(DB_PATH, timeout=2.0)
            conn.row_factory = sqlite3.Row
            try:
                cursor = conn.execute(
                    "SELECT chain_id, label, name_tag, updated_at FROM accounts WHERE address = ? LIMIT 50",
                    (address.lower(),),
                )
                labels = []
                for row in cursor:
                    chain_id = row["chain_id"]
                    chain_name = _CHAIN_ID_MAP.get(chain_id, f"chain-{chain_id}")
                    label_value = row["name_tag"] or row["label"]
                    if not label_value:
                        continue
                    labels.append(
                        Label(
                            address=address.lower(),
                            chain=chain_name,
                            label_type="entity",
                            label_value=label_value,
                            source=LabelSource.ETH_LABELS_DB,
                            confidence=0.9,  # eth-labels.db is curated
                            verified_at=_parse_date(row["updated_at"]),
                            attributes={"chain_id": chain_id, "raw_label": row["label"]},
                        )
                    )
                return labels
            finally:
                conn.close()
        except Exception as e:
            log.warning("eth_labels_db_query_fail address=%s err=%s", address[:10], e)
            raise

    return await asyncio.to_thread(_query)


def _parse_date(s: str | None) -> datetime:
    """Parse SQLite date string to datetime."""
    if not s:
        return datetime.now(UTC)
    try:
        # Format: '2024-06-30 21:58:54'
        return datetime.fromisoformat(s).replace(tzinfo=UTC)
    except Exception:
        return datetime.now(UTC)
