"""
🌙 Luna-Py - Ultimate All-in-One Python Library
Discord Bots, Webhooks, HTTP Client, TrueWallet API, and more!
"""

__version__ = "1.0.0"
__author__ = "Your Name"

import discord
from discord.ext import commands
import requests
import aiohttp
import asyncio
import base64
import secrets
import time
from datetime import datetime
from typing import Optional, List, Dict, Any
import re

# ========================================
# 🤖 DISCORD BOT MODULE
# ========================================

class LunaBot:
    """Easy Discord Bot Creator"""
    
    @staticmethod
    def create_bot(command_prefix: str = "!", intents: Optional[discord.Intents] = None):
        """
        Create a Discord Bot with easy command handling
        
        Args:
            command_prefix: Command prefix (default: "!")
            intents: Discord intents (default: all intents)
        
        Returns:
            commands.Bot instance
        """
        if intents is None:
            intents = discord.Intents.all()
        
        bot = commands.Bot(command_prefix=command_prefix, intents=intents)
        
        # Add helper methods
        bot.luna_reply_embed = lambda ctx, **kwargs: LunaEmbed.reply(ctx, **kwargs)
        
        return bot
    
    @staticmethod
    def create_client(intents: Optional[discord.Intents] = None):
        """
        Create a Discord Client (without commands)
        
        Args:
            intents: Discord intents (default: all intents)
        
        Returns:
            discord.Client instance
        """
        if intents is None:
            intents = discord.Intents.all()
        
        return discord.Client(intents=intents)


class LunaEmbed:
    """Easy Embed Creator"""
    
    # Color presets
    RED = 0xFF0000
    GREEN = 0x00FF00
    BLUE = 0x0000FF
    YELLOW = 0xFFFF00
    PURPLE = 0x800080
    ORANGE = 0xFFA500
    DISCORD = 0x5865F2
    SUCCESS = 0x00FF00
    ERROR = 0xFF0000
    WARNING = 0xFFFF00
    INFO = 0x0099FF
    
    @staticmethod
    def create(
        title: Optional[str] = None,
        description: Optional[str] = None,
        color: int = DISCORD,
        fields: Optional[List[Dict[str, Any]]] = None,
        thumbnail: Optional[str] = None,
        image: Optional[str] = None,
        footer: Optional[str] = None,
        timestamp: bool = False,
        url: Optional[str] = None,
        author: Optional[Dict[str, str]] = None
    ) -> discord.Embed:
        """
        Create a Discord Embed
        
        Args:
            title: Embed title
            description: Embed description
            color: Embed color (hex)
            fields: List of fields [{"name": "", "value": "", "inline": False}]
            thumbnail: Thumbnail URL
            image: Image URL
            footer: Footer text
            timestamp: Add timestamp
            url: URL when clicking title
            author: Author dict {"name": "", "icon_url": ""}
        
        Returns:
            discord.Embed
        """
        embed = discord.Embed(
            title=title,
            description=description,
            color=color,
            url=url
        )
        
        if fields:
            for field in fields:
                embed.add_field(
                    name=field.get("name", ""),
                    value=field.get("value", ""),
                    inline=field.get("inline", False)
                )
        
        if thumbnail:
            embed.set_thumbnail(url=thumbnail)
        
        if image:
            embed.set_image(url=image)
        
        if footer:
            embed.set_footer(text=footer)
        
        if timestamp:
            embed.timestamp = datetime.utcnow()
        
        if author:
            embed.set_author(
                name=author.get("name", ""),
                icon_url=author.get("icon_url")
            )
        
        return embed
    
    @staticmethod
    async def reply(ctx, **kwargs):
        """Quick embed reply to a command"""
        embed = LunaEmbed.create(**kwargs)
        return await ctx.reply(embed=embed)


class LunaButton:
    """Easy Button Creator"""
    
    @staticmethod
    def create(
        label: str,
        custom_id: str,
        style: discord.ButtonStyle = discord.ButtonStyle.primary,
        emoji: Optional[str] = None,
        url: Optional[str] = None,
        disabled: bool = False
    ) -> discord.ui.Button:
        """
        Create a Discord Button
        
        Args:
            label: Button label
            custom_id: Button ID
            style: Button style
            emoji: Button emoji
            url: URL for link buttons
            disabled: Disabled state
        
        Returns:
            discord.ui.Button
        """
        if url:
            return discord.ui.Button(
                label=label,
                url=url,
                emoji=emoji,
                disabled=disabled
            )
        
        return discord.ui.Button(
            label=label,
            custom_id=custom_id,
            style=style,
            emoji=emoji,
            disabled=disabled
        )


class LunaView(discord.ui.View):
    """Easy View with Buttons"""
    
    def __init__(self, *buttons, timeout: float = 180):
        super().__init__(timeout=timeout)
        for button in buttons:
            self.add_item(button)


# ========================================
# 📨 DISCORD WEBHOOK MODULE
# ========================================

class LunaWebhook:
    """Discord Webhook Manager"""
    
    @staticmethod
    def send(
        webhook_url: str,
        content: Optional[str] = None,
        username: Optional[str] = "Luna Bot",
        avatar_url: Optional[str] = None,
        embeds: Optional[List[discord.Embed]] = None,
        tts: bool = False
    ) -> Dict[str, Any]:
        """
        Send message to Discord webhook
        
        Args:
            webhook_url: Webhook URL
            content: Message content
            username: Bot username
            avatar_url: Bot avatar URL
            embeds: List of embeds
            tts: Text-to-speech
        
        Returns:
            Response dict
        """
        payload = {
            "content": content,
            "username": username,
            "avatar_url": avatar_url,
            "tts": tts
        }
        
        if embeds:
            payload["embeds"] = [embed.to_dict() for embed in embeds]
        
        try:
            response = requests.post(webhook_url, json=payload)
            response.raise_for_status()
            return {"success": True, "status": response.status_code}
        except Exception as e:
            return {"success": False, "error": str(e)}
    
    @staticmethod
    def send_embed(
        webhook_url: str,
        embed: discord.Embed,
        username: Optional[str] = "Luna Bot",
        avatar_url: Optional[str] = None
    ) -> Dict[str, Any]:
        """Send embed to webhook"""
        return LunaWebhook.send(
            webhook_url,
            embeds=[embed],
            username=username,
            avatar_url=avatar_url
        )


# ========================================
# 🌐 HTTP CLIENT MODULE
# ========================================

class LunaHTTP:
    """HTTP Client with auto-retry"""
    
    def __init__(self, timeout: int = 30, max_retries: int = 3):
        self.timeout = timeout
        self.max_retries = max_retries
        self.session = requests.Session()
    
    def request(
        self,
        method: str,
        url: str,
        **kwargs
    ) -> requests.Response:
        """
        Make HTTP request with auto-retry
        
        Args:
            method: HTTP method (GET, POST, etc.)
            url: Request URL
            **kwargs: Additional arguments for requests
        
        Returns:
            requests.Response
        """
        kwargs.setdefault('timeout', self.timeout)
        
        for attempt in range(1, self.max_retries + 1):
            try:
                response = self.session.request(method, url, **kwargs)
                response.raise_for_status()
                return response
            except requests.exceptions.RequestException as e:
                if attempt == self.max_retries:
                    raise
                time.sleep(min(2 ** (attempt - 1), 5))
        
        raise Exception("Max retries exceeded")
    
    def get(self, url: str, **kwargs) -> requests.Response:
        """GET request"""
        return self.request("GET", url, **kwargs)
    
    def post(self, url: str, **kwargs) -> requests.Response:
        """POST request"""
        return self.request("POST", url, **kwargs)
    
    def put(self, url: str, **kwargs) -> requests.Response:
        """PUT request"""
        return self.request("PUT", url, **kwargs)
    
    def delete(self, url: str, **kwargs) -> requests.Response:
        """DELETE request"""
        return self.request("DELETE", url, **kwargs)


# ========================================
# 💰 TRUEWALLET MODULE
# ========================================

class LunaTrueWallet:
    """TrueWallet Voucher API"""
    
    @staticmethod
    def redeem_voucher(voucher_link: str, phone_number: str) -> Dict[str, Any]:
        """
        Redeem TrueWallet voucher
        
        Args:
            voucher_link: Voucher link or code
            phone_number: Phone number to receive
        
        Returns:
            Result dict
        """
        # Extract voucher code
        voucher_code = re.sub(
            r"https://gift\.truemoney\.com/campaign/\?v=",
            "",
            voucher_link
        )
        
        url = f"https://gift.truemoney.com/campaign/vouchers/{voucher_code}/redeem"
        
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
            "Content-Type": "application/json"
        }
        
        data = {"mobile": phone_number}
        
        try:
            response = requests.post(url, json=data, headers=headers)
            return response.json()
        except Exception as e:
            return {"error": str(e)}


# ========================================
# 🛠️ UTILITIES MODULE
# ========================================

class LunaUtils:
    """Utility Functions"""
    
    @staticmethod
    def sleep(seconds: float):
        """Sleep for specified seconds"""
        time.sleep(seconds)
    
    @staticmethod
    async def async_sleep(seconds: float):
        """Async sleep for specified seconds"""
        await asyncio.sleep(seconds)
    
    @staticmethod
    def random(min_val: int, max_val: int) -> int:
        """Random number between min and max"""
        return secrets.randbelow(max_val - min_val + 1) + min_val
    
    @staticmethod
    def random_string(length: int = 10) -> str:
        """Generate random string"""
        import string
        chars = string.ascii_letters + string.digits
        return ''.join(secrets.choice(chars) for _ in range(length))
    
    @staticmethod
    def format_number(num: int) -> str:
        """Format number with commas"""
        return f"{num:,}"
    
    @staticmethod
    def chunk_list(lst: List, size: int) -> List[List]:
        """Split list into chunks"""
        return [lst[i:i + size] for i in range(0, len(lst), size)]
    
    @staticmethod
    def timestamp() -> int:
        """Get current Unix timestamp"""
        return int(time.time())
    
    @staticmethod
    def format_date(
        dt: Optional[datetime] = None,
        format_str: str = "%Y-%m-%d %H:%M:%S"
    ) -> str:
        """Format datetime"""
        if dt is None:
            dt = datetime.now()
        return dt.strftime(format_str)


# ========================================
# 🔐 CRYPTO MODULE
# ========================================

class LunaCrypto:
    """Crypto and Encoding Functions"""
    
    @staticmethod
    def base64_encode(text: str) -> str:
        """Encode string to base64"""
        return base64.b64encode(text.encode()).decode()
    
    @staticmethod
    def base64_decode(encoded: str) -> str:
        """Decode base64 to string"""
        return base64.b64decode(encoded.encode()).decode()
    
    @staticmethod
    def generate_token(length: int = 32) -> str:
        """Generate random token"""
        return secrets.token_hex(length)


# ========================================
# 📊 EXPORT ALL
# ========================================

__all__ = [
    # Bot
    "LunaBot",
    "LunaEmbed",
    "LunaButton",
    "LunaView",
    # Webhook
    "LunaWebhook",
    # HTTP
    "LunaHTTP",
    # TrueWallet
    "LunaTrueWallet",
    # Utils
    "LunaUtils",
    # Crypto
    "LunaCrypto",
]
