"""
AkDevz AI Market Intelligence — Angel One SmartAPI Broker Adapter
Genuinely free retail trading and market data API.
Supports TOTP authentication, live market quotes, positions, and orders.
"""
import time
import logging
from typing import Dict, Any, List, Optional
from python.brokers.base_broker import BaseBrokerAdapter

logger = logging.getLogger(__name__)

class AngelOneBrokerAdapter(BaseBrokerAdapter):
    BASE_URL = "https://apiconnect.angelbroking.com"

    def __init__(self, credentials: Dict[str, Any]):
        super().__init__("ANGEL_ONE", credentials)
        self.client_code = credentials.get("client_id", "")
        self.api_key = credentials.get("api_key", "")
        self.pin_totp = credentials.get("pin_totp", "")
        self.jwt_token = credentials.get("access_token", "")
        self.feed_token = credentials.get("feed_token", "")

    def authenticate(self) -> bool:
        """
        Authenticates with SmartAPI using Client Code, PIN, and TOTP.
        If TOTP is configured, generates current token and logs in.
        """
        if self.jwt_token and len(self.jwt_token) > 20:
            self.is_authenticated = True
            return True

        if not (self.client_code and self.api_key and self.pin_totp):
            return False

        try:
            import pyotp
            totp = pyotp.TOTP(self.pin_totp).now()
        except Exception:
            totp = self.pin_totp

        import requests
        headers = {
            "Content-Type": "application/json",
            "Accept": "application/json",
            "X-UserType": "USER",
            "X-SourceID": "WEB",
            "X-ClientLocalIP": "127.0.0.1",
            "X-ClientPublicIP": "127.0.0.1",
            "X-MACAddress": "fe80::1",
            "X-PrivateKey": self.api_key
        }
        payload = {
            "clientcode": self.client_code,
            "password": self.pin_totp,
            "totp": totp
        }
        try:
            resp = requests.post(f"{self.BASE_URL}/rest/auth/partner/v1/loginByPassword", json=payload, headers=headers, timeout=10)
            if resp.status_code == 200:
                data = resp.json()
                if data.get("status"):
                    res_data = data.get("data", {})
                    self.jwt_token = res_data.get("jwtToken", "")
                    self.feed_token = res_data.get("feedToken", "")
                    self.is_authenticated = True
                    return True
        except Exception as e:
            logger.warning(f"Angel One login error: {e}")
        return False

    def get_quotes(self, symbols: List[str]) -> Dict[str, Dict[str, Any]]:
        """Queries Angel One market quote endpoint."""
        if not self.jwt_token:
            return {}
        import requests
        headers = {
            "Authorization": f"Bearer {self.jwt_token}",
            "Content-Type": "application/json",
            "Accept": "application/json",
            "X-PrivateKey": self.api_key
        }
        quotes = {}
        # Angel One uses token/exchange query
        for sym in symbols[:15]:
            clean = sym.replace("NSE:", "").replace("-EQ", "").replace("-INDEX", "")
            try:
                resp = requests.post(f"{self.BASE_URL}/rest/secure/angelbroking/market/v1/quote", json={
                    "mode": "FULL",
                    "exchangeTokens": {"NSE": [clean]}
                }, headers=headers, timeout=5)
                if resp.status_code == 200:
                    data = resp.json().get("data", {})
                    if data:
                        quotes[sym] = {
                            "symbol": sym,
                            "ltp": float(data.get("ltp", 0.0)),
                            "open": float(data.get("open", 0.0)),
                            "high": float(data.get("high", 0.0)),
                            "low": float(data.get("low", 0.0)),
                            "close": float(data.get("close", 0.0)),
                            "volume": int(data.get("tradeVolume", 0)),
                            "change_pct": float(data.get("changePercent", 0.0)),
                            "timestamp": int(time.time()),
                            "provider": "ANGEL_ONE"
                        }
            except Exception:
                continue
        return quotes

    def get_historical_candles(self, symbol: str, resolution: str = "5", range_from: str = "", range_to: str = "") -> List[List[Any]]:
        return []

    def get_option_chain(self, symbol: str, strike_count: int = 15) -> Optional[Dict[str, Any]]:
        return None

    def get_funds_and_margin(self) -> Dict[str, Any]:
        if not self.jwt_token:
            return {"available_funds": 0.0, "used_margin": 0.0, "status": "UNAUTHENTICATED"}
        import requests
        headers = {
            "Authorization": f"Bearer {self.jwt_token}",
            "Content-Type": "application/json",
            "X-PrivateKey": self.api_key
        }
        try:
            resp = requests.get(f"{self.BASE_URL}/rest/secure/angelbroking/user/v1/getRMS", headers=headers, timeout=8)
            if resp.status_code == 200:
                d = resp.json().get("data", {})
                avail = float(d.get("net", 0.0))
                used = float(d.get("utilizedAmount", 0.0))
                return {"available_funds": avail, "used_margin": used, "status": "CONNECTED", "provider": "ANGEL_ONE"}
        except Exception:
            pass
        return {"available_funds": 0.0, "used_margin": 0.0, "status": "ERROR"}

    def get_positions(self) -> List[Dict[str, Any]]:
        if not self.jwt_token:
            return []
        import requests
        headers = {"Authorization": f"Bearer {self.jwt_token}", "X-PrivateKey": self.api_key}
        try:
            resp = requests.get(f"{self.BASE_URL}/rest/secure/angelbroking/order/v1/getPosition", headers=headers, timeout=8)
            if resp.status_code == 200:
                return resp.json().get("data", []) or []
        except Exception:
            pass
        return []

    def place_order(self, order_params: Dict[str, Any]) -> Dict[str, Any]:
        if not self.jwt_token:
            return {"status": "error", "message": "Angel One token not present"}
        import requests
        headers = {
            "Authorization": f"Bearer {self.jwt_token}",
            "Content-Type": "application/json",
            "X-PrivateKey": self.api_key
        }
        try:
            resp = requests.post(f"{self.BASE_URL}/rest/secure/angelbroking/order/v1/placeOrder", json=order_params, headers=headers, timeout=10)
            return resp.json()
        except Exception as e:
            return {"status": "error", "message": str(e)}

    def modify_order(self, order_id: str, params: Dict[str, Any]) -> Dict[str, Any]:
        return {"status": "error", "message": "Not implemented"}

    def cancel_order(self, order_id: str) -> Dict[str, Any]:
        return {"status": "error", "message": "Not implemented"}
