"""
AkDevz AI Market Intelligence — Centralized FYERS Rate Limiter
Enforces Leaky-Bucket / Token-Bucket limits for FYERS Standard API V3:
- 5 requests/second
- 50 requests/minute
- 5,000 requests/day
"""
import time
import threading
from typing import Optional

class FyersRateLimiter:
    _instance: Optional["FyersRateLimiter"] = None
    _lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        with cls._lock:
            if cls._instance is None:
                cls._instance = super(FyersRateLimiter, cls).__new__(cls)
                cls._instance._init_limiter()
            return cls._instance

    def _init_limiter(self):
        self.req_per_sec = 5
        self.req_per_min = 50
        self.req_per_day = 5000

        self.sec_window = []
        self.min_window = []
        self.daily_count = 0
        self.day_start = time.time()
        self.throttle_lock = threading.Lock()

    def acquire(self):
        with self.throttle_lock:
            now = time.time()

            # Reset day counter every 24 hours
            if now - self.day_start > 86400:
                self.daily_count = 0
                self.day_start = now

            if self.daily_count >= self.req_per_day:
                raise RuntimeError(
                    f"FYERS Daily API Quota of {self.req_per_day} requests reached. "
                    "Halting further requests until daily quota resets at 06:30 AM IST."
                )

            # Purge records older than 1 second
            self.sec_window = [t for t in self.sec_window if now - t < 1.0]
            if len(self.sec_window) >= self.req_per_sec:
                sleep_needed = 1.0 - (now - self.sec_window[0]) + 0.05
                if sleep_needed > 0:
                    time.sleep(sleep_needed)
                now = time.time()
                self.sec_window = [t for t in self.sec_window if now - t < 1.0]

            # Purge records older than 60 seconds
            self.min_window = [t for t in self.min_window if now - t < 60.0]
            if len(self.min_window) >= self.req_per_min:
                sleep_needed = 60.0 - (now - self.min_window[0]) + 0.1
                if sleep_needed > 0:
                    time.sleep(sleep_needed)
                now = time.time()
                self.min_window = [t for t in self.min_window if now - t < 60.0]

            # Record timestamp
            self.sec_window.append(now)
            self.min_window.append(now)
            self.daily_count += 1

    def get_stats(self) -> dict:
        with self.throttle_lock:
            now = time.time()
            sec_count = len([t for t in self.sec_window if now - t < 1.0])
            min_count = len([t for t in self.min_window if now - t < 60.0])
            return {
                "current_req_per_sec": sec_count,
                "current_req_per_min": min_count,
                "daily_requests_used": self.daily_count,
                "daily_quota": self.req_per_day,
                "remaining_daily_requests": max(0, self.req_per_day - self.daily_count)
            }

rate_limiter = FyersRateLimiter()
