"""Exchange configuration wrappers."""

from __future__ import annotations

import logging
import os
from dataclasses import dataclass, field

logger = logging.getLogger("horizon")


def _env(key: str) -> str | None:
    """Read from environment, stripping whitespace."""
    val = os.environ.get(key)
    return val.strip() if val else None


@dataclass
class Polymarket:
    """Polymarket exchange configuration.

    Credentials are resolved in this order:
    1. Explicit constructor arguments
    2. Environment variables (POLYMARKET_PRIVATE_KEY, POLYMARKET_API_KEY, etc.)

    Usage:
        Polymarket(private_key="0x...")  # explicit
        Polymarket()                     # from env vars
    """

    private_key: str | None = field(default=None)
    clob_url: str = "https://clob.polymarket.com"
    gamma_url: str = "https://gamma-api.polymarket.com"
    api_key: str | None = None
    api_secret: str | None = None
    api_passphrase: str | None = None

    def __post_init__(self):
        # Resolve from environment if not provided
        if self.private_key is None:
            self.private_key = _env("POLYMARKET_PRIVATE_KEY")
        if self.api_key is None:
            self.api_key = _env("POLYMARKET_API_KEY")
        if self.api_secret is None:
            self.api_secret = _env("POLYMARKET_API_SECRET")
        if self.api_passphrase is None:
            self.api_passphrase = _env("POLYMARKET_API_PASSPHRASE")

        if self.private_key and not self.api_key:
            logger.info(
                "Polymarket: private_key set but no api_key. "
                "Will attempt to derive API credentials from CLOB."
            )

    def derive_api_credentials(self) -> None:
        """Derive api_key/api_secret/api_passphrase from private_key via CLOB API.

        Calls POST /auth/derive-api-key with the wallet signature.
        This is a convenience method - call it before hz.run() if you only have a private key.
        """
        if not self.private_key:
            raise ValueError("private_key is required to derive API credentials")

        if self.api_key and self.api_secret and self.api_passphrase:
            return  # Already have credentials

        import time

        import requests

        url = f"{self.clob_url}/auth/derive-api-key"
        timestamp = int(time.time())
        nonce = timestamp

        # Sign CLOB auth message with private key using eth_account
        try:
            from eth_account import Account
            from eth_account.messages import encode_defunct

            account = Account.from_key(self.private_key)
            msg = encode_defunct(text=f"{timestamp}{nonce}")
            signed = account.sign_message(msg)
            signature = signed.signature.hex()
            address = account.address
        except ImportError:
            raise RuntimeError(
                "Cannot derive API credentials: install eth_account "
                "(`pip install eth-account`) or provide api_key/api_secret/api_passphrase directly"
            )

        body = {
            "timestamp": str(timestamp),
            "nonce": str(nonce),
            "signature": signature,
            "address": address,
        }

        resp = requests.post(url, json=body, timeout=30)
        if not resp.ok:
            raise RuntimeError(
                f"Failed to derive API credentials: {resp.status_code} {resp.text}"
            )

        data = resp.json()
        self.api_key = data.get("apiKey") or data.get("key")
        self.api_secret = data.get("secret")
        self.api_passphrase = data.get("passphrase")

        if not self.api_key:
            raise RuntimeError(f"Unexpected response from derive-api-key: {data}")

        logger.info("Polymarket: API credentials derived successfully")


@dataclass
class Kalshi:
    """Kalshi exchange configuration.

    Credentials are resolved in this order:
    1. Explicit constructor arguments
    2. Environment variables (KALSHI_EMAIL, KALSHI_PASSWORD, KALSHI_API_KEY)

    Usage:
        Kalshi(email="...", password="...")  # explicit
        Kalshi()                             # from env vars
    """

    email: str | None = None
    password: str | None = None
    api_key: str | None = None
    api_url: str = "https://trading-api.kalshi.com/trade-api/v2"

    def __post_init__(self):
        if self.email is None:
            self.email = _env("KALSHI_EMAIL")
        if self.password is None:
            self.password = _env("KALSHI_PASSWORD")
        if self.api_key is None:
            self.api_key = _env("KALSHI_API_KEY")
        if env_url := _env("KALSHI_API_URL"):
            self.api_url = env_url
