import time
import re
import discord
from datetime import datetime, timezone
import config
from database import db
from utils.logger import log_suspicious_activity

import math

def parse_money_string(val_str: str) -> float:
    """
    Safely parses money inputs supporting suffix shortcuts:
    100k -> 100,000
    1.5m -> 1,500,000
    2.5b -> 2,500,000,000
    Rejects negatives, NaN, Infinity, and invalid characters.
    """
    if not val_str:
        return 0.0
        
    s = str(val_str).strip().lower()
    
    # Strictly reject negative signs or invalid keywords
    if "-" in s or "nan" in s or "inf" in s:
        return 0.0
    
    # Match number followed by suffix (k, m, b)
    match = re.match(r"^([\d\.,]+)\s*([mkb])$", s)
    if match:
        try:
            num_val = float(match.group(1).replace(",", ""))
            unit = match.group(2)
            if unit == 'k':
                res = num_val * 1_000.0
            elif unit == 'm':
                res = num_val * 1_000_000.0
            elif unit == 'b':
                res = num_val * 1_000_000_000.0
            else:
                res = num_val
            
            if not math.isfinite(res) or res <= 0 or res > 100_000_000_000_000.0:
                return 0.0
            return round(res, 2)
        except (ValueError, OverflowError):
            return 0.0
            
    # Try standard numeric float parse
    clean = re.sub(r"[^\d\.]", "", s.replace(",", ""))
    if not clean:
        return 0.0
    try:
        res = float(clean)
        if not math.isfinite(res) or res <= 0 or res > 100_000_000_000_000.0:
            return 0.0
        return round(res, 2)
    except (ValueError, OverflowError):
        return 0.0

def format_money_string(amount: float) -> str:
    """
    Formats a float amount into a concise string with suffixes:
    1500 -> 1.5k
    1000000 -> 1m
    2500000000 -> 2.5b
    -1000000 -> -1m
    """
    amount = float(amount)
    sign = "-" if amount < 0 else ""
    abs_amount = abs(amount)
    if abs_amount >= 1_000_000_000:
        val = abs_amount / 1_000_000_000
        return f"{sign}{val:,.2f}".rstrip('0').rstrip('.') + "b"
    elif abs_amount >= 1_000_000:
        val = abs_amount / 1_000_000
        return f"{sign}{val:,.2f}".rstrip('0').rstrip('.') + "m"
    elif abs_amount >= 1_000:
        val = abs_amount / 1_000
        return f"{sign}{val:,.2f}".rstrip('0').rstrip('.') + "k"
    else:
        return f"{sign}{abs_amount:,.2f}".rstrip('0').rstrip('.')

import asyncio

async def schedule_message_delete(message, delay: float = 10.0):
    """Asynchronously deletes a message after specified delay in seconds."""
    if not message:
        return
    await asyncio.sleep(delay)
    try:
        if isinstance(message, discord.WebhookMessage) or isinstance(message, discord.Message):
            await message.delete()
        elif hasattr(message, "delete_original_response"):
            await message.delete_original_response()
    except Exception:
        pass

class InteractionRateLimiter:
    def __init__(self, cooldown_seconds: float):
        self.cooldown_seconds = cooldown_seconds
        self.last_used = {}

    def check_cooldown(self, user_id: int) -> float:
        """
        Checks if the user is rate limited.
        Returns the remaining cooldown time in seconds if limited, otherwise 0.
        """
        now = time.time()
        if user_id in self.last_used:
            elapsed = now - self.last_used[user_id]
            if elapsed < self.cooldown_seconds:
                return self.cooldown_seconds - elapsed
        
        self.last_used[user_id] = now
        return 0.0

    def reset_cooldown(self, user_id: int):
        """Resets the cooldown for a user."""
        if user_id in self.last_used:
            del self.last_used[user_id]

# Instantiate global limiter
rate_limiter = InteractionRateLimiter(config.COMMAND_COOLDOWN_SECONDS)

async def check_security_compliance(interaction: discord.Interaction) -> bool:
    """
    Performs critical security compliance checks:
    1. Check for command/button spam (Rate Limiting).
    2. Check for Alt accounts (Account Age).
    3. Check for ban status.
    
    Returns True if user is compliant, otherwise sends an error interaction response and returns False.
    """
    user = interaction.user
    
    # 1. Rate Limiting Check
    remaining = rate_limiter.check_cooldown(user.id)
    if remaining > 0:
        await interaction.response.send_message(
            f"⚠️ **Çok hızlı işlem yapıyorsunuz!** Lütfen `{remaining:.1f}` saniye bekleyin.",
            ephemeral=True
        )
        return False

    # 2. Account Age Check (Alt account protection)
    # discord.Interaction has a created_at timezone-aware timestamp
    account_age_days = (datetime.now(timezone.utc) - user.created_at).days
    if account_age_days < config.ALT_ACCOUNT_AGE_DAYS:
        # Prevent usage and alert admins
        details = f"Hesap yaşı: {account_age_days} gün (Limit: {config.ALT_ACCOUNT_AGE_DAYS} gün). Bot kullanımı engellendi."
        await log_suspicious_activity(interaction.client, user, "Alt_Account_Detected", details)
        
        await interaction.response.send_message(
            f"❌ **Güvenlik Engeli**: Sunucu ekonomisinin güvenliği nedeniyle, hesabı `{config.ALT_ACCOUNT_AGE_DAYS}` günden yeni olan kullanıcılar bu botu kullanamaz.",
            ephemeral=True
        )
        return False

    # 3. Database ban check
    user_db = await db.get_user(user.id)
    if user_db and user_db.get("is_banned"):
        await interaction.response.send_message(
            "❌ **Erişim Engellendi**: Bot ekonomisinden ve kumar oyunlarından uzaklaştırıldınız (Yasaklandınız).",
            ephemeral=True
        )
        return False

    # 4. Global Killswitch / Maintenance check
    if hasattr(config, "GAMES_ENABLED") and not config.GAMES_ENABLED:
        # If user is not administrator, block game actions
        is_admin = False
        if interaction.guild and interaction.user.guild_permissions.administrator:
            is_admin = True
        
        if not is_admin:
            await interaction.response.send_message(
                "🛑 **Bakım & Güvenlik Modu:** Kumar oyunları bir yönetici tarafından geçici olarak durdurulmuştur (Donduruldu). Lütfen daha sonra tekrar deneyin.",
                ephemeral=True
            )
            return False

    return True
