"""
Telegram Notification Utility for SOL API
Provides functions to send messages, alerts, and reports to Telegram channels
"""

import aiohttp
import asyncio
import json
from datetime import datetime
from typing import Optional, Dict, List, Any
from urllib.parse import quote

from utils.config import *
from utils.logger import tg_logger as telegram_logger

class TelegramNotifier:
    """
    Telegram notification handler for SOL API
    Supports sending messages, formatted reports, and alerts
    """
    
    def __init__(self, bot_token: str = None, chat_id: str = None, topic_id: str = None):
        """
        Initialize Telegram notifier
        
        Args:
            bot_token: Telegram bot token (from BotFather)
            chat_id: Target chat/channel ID
            topic_id: Optional topic ID for groups with topics
        """
        self.bot_token = bot_token or TELEGRAM_BOT_TOKEN
        self.chat_id = chat_id or TELEGRAM_CHAT_ID
        self.topic_id = topic_id or TELEGRAM_TOPIC_ID
        self.base_url = f"https://api.telegram.org/bot{self.bot_token}" if self.bot_token else None
        
        if not self.bot_token or not self.chat_id:
            telegram_logger.warning("⚠️ Telegram credentials not configured")

    async def send_message(self, message: str, parse_mode: str = "HTML", 
                          disable_web_page_preview: bool = True) -> bool:
        """
        Send a message to the configured Telegram chat
        
        Args:
            message: Message text to send
            parse_mode: Parsing mode (HTML, Markdown, or None)
            disable_web_page_preview: Whether to disable link previews
            
        Returns:
            bool: True if successful, False otherwise
        """
        if not self.base_url:
            telegram_logger.error("❌ Telegram not configured")
            return False
        
        try:
            url = f"{self.base_url}/sendMessage"
            payload = {
                "chat_id": self.chat_id,
                "text": message,
                "parse_mode": parse_mode,
                "disable_web_page_preview": disable_web_page_preview
            }
            
            # Add topic ID if specified (for groups with topics)
            if self.topic_id:
                payload["message_thread_id"] = self.topic_id
            
            async with aiohttp.ClientSession() as session:
                async with session.post(url, json=payload) as response:
                    if response.status == 200:
                        result = await response.json()
                        if result.get("ok"):
                            telegram_logger.info("📱 Message sent to Telegram successfully")
                            return True
                        else:
                            telegram_logger.error(f"❌ Telegram API error: {result}")
                            return False
                    else:
                        error_text = await response.text()
                        telegram_logger.error(f"❌ HTTP error {response.status}: {error_text}")
                        return False
                        
        except Exception as e:
            telegram_logger.error(f"❌ Error sending Telegram message: {e}", exc_info=True)
            return False

    async def send_alert(self, title: str, message: str, level: str = "INFO") -> bool:
        """
        Send a formatted alert message
        
        Args:
            title: Alert title
            message: Alert message
            level: Alert level (INFO, WARNING, ERROR, SUCCESS)
            
        Returns:
            bool: True if successful, False otherwise
        """
        emoji_map = {
            "INFO": "ℹ️",
            "WARNING": "⚠️", 
            "ERROR": "❌",
            "SUCCESS": "✅",
            "CRITICAL": "🚨"
        }
        
        emoji = emoji_map.get(level.upper(), "📢")
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        
        formatted_message = f"""
{emoji} <b>{title}</b>

{message}

<i>Time: {timestamp}</i>
<i>Level: {level}</i>
        """.strip()
        
        return await self.send_message(formatted_message)

    async def send_token_processing_report(self, stats: Dict[str, Any]) -> bool:
        """
        Send a token processing completion report
        
        Args:
            stats: Statistics dictionary from token processing
            
        Returns:
            bool: True if successful, False otherwise
        """
        try:
            total = stats.get('total_processed', 0)
            good = stats.get('good_tokens', 0)
            bad = stats.get('bad_tokens', 0)
            already_processed = stats.get('already_processed', 0)
            
            pump_tokens = stats.get('good_pump_tokens', 0)
            bonk_tokens = stats.get('good_bonk_tokens', 0)
            
            success_rate = (good / total * 100) if total > 0 else 0
            
            message = f"""
🏁 <b>Token Processing Complete</b>

📊 <b>Statistics:</b>
• Total processed: {total}
• ✅ Good tokens: {good}
• ❌ Bad tokens: {bad}
• ⚠️ Already processed: {already_processed}

🎯 <b>Success Rate:</b> {success_rate:.1f}%

💰 <b>Token Distribution:</b>
• 🔵 PUMP tokens: {pump_tokens}
• 🟠 BONK tokens: {bonk_tokens}

<i>Next: Processing wallets for valid tokens</i>
            """.strip()
            
            return await self.send_message(message)
            
        except Exception as e:
            telegram_logger.error(f"❌ Error sending token report: {e}", exc_info=True)
            return False

    async def send_wallet_processing_report(self, wallet_count: int, processing_time: float = None) -> bool:
        """
        Send a wallet processing completion report
        
        Args:
            wallet_count: Number of wallets processed
            processing_time: Time taken in seconds
            
        Returns:
            bool: True if successful, False otherwise
        """
        try:
            time_str = f"\n⏱️ <b>Processing Time:</b> {processing_time:.1f} seconds" if processing_time else ""
            
            message = f"""
👛 <b>Wallet Processing Complete</b>

📊 <b>Results:</b>
• Wallets processed: {wallet_count}{time_str}

✅ All wallet transactions have been analyzed and classified.
            """.strip()
            
            return await self.send_message(message)
            
        except Exception as e:
            telegram_logger.error(f"❌ Error sending wallet report: {e}", exc_info=True)
            return False

    async def send_system_status(self, services: Dict[str, str]) -> bool:
        """
        Send system status report
        
        Args:
            services: Dictionary of service_name -> status
            
        Returns:
            bool: True if successful, False otherwise
        """
        try:
            status_lines = []
            for service, status in services.items():
                emoji = "🟢" if status.lower() in ["running", "active", "ok"] else "🔴"
                status_lines.append(f"• {emoji} {service}: {status}")
            
            message = f"""
🖥️ <b>System Status Report</b>

{chr(10).join(status_lines)}

<i>Timestamp: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}</i>
            """.strip()
            
            return await self.send_message(message)
            
        except Exception as e:
            telegram_logger.error(f"❌ Error sending status report: {e}", exc_info=True)
            return False

    async def send_error_alert(self, error: str, context: str = None) -> bool:
        """
        Send an error alert
        
        Args:
            error: Error message
            context: Additional context information
            
        Returns:
            bool: True if successful, False otherwise
        """
        context_str = f"\n\n<b>Context:</b> {context}" if context else ""
        
        message = f"""
🚨 <b>Error Alert</b>

<b>Error:</b> {error}{context_str}

<i>Time: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}</i>
        """.strip()
        
        return await self.send_alert("System Error", message, "ERROR")

    async def send_performance_report(self, rps: float, efficiency: float, 
                                    total_requests: int, processing_time: float) -> bool:
        """
        Send performance metrics report
        
        Args:
            rps: Requests per second achieved
            efficiency: Efficiency percentage
            total_requests: Total requests processed
            processing_time: Total processing time in seconds
            
        Returns:
            bool: True if successful, False otherwise
        """
        try:
            message = f"""
⚡ <b>Performance Report</b>

📈 <b>Metrics:</b>
• RPS Achieved: {rps:.1f}
• Efficiency: {efficiency:.1f}%
• Total Requests: {total_requests:,}
• Processing Time: {processing_time:.1f}s

🎯 <b>Target RPS:</b> 200
            """.strip()
            
            return await self.send_message(message)
            
        except Exception as e:
            telegram_logger.error(f"❌ Error sending performance report: {e}", exc_info=True)
            return False

    async def send_coordination_update(self, bonk_finished: bool, pump_finished: bool) -> bool:
        """
        Send coordination status update
        
        Args:
            bonk_finished: Whether BONK processing is finished
            pump_finished: Whether PUMP processing is finished
            
        Returns:
            bool: True if successful, False otherwise
        """
        try:
            bonk_status = "✅ Finished" if bonk_finished else "⏳ Processing"
            pump_status = "✅ Finished" if pump_finished else "⏳ Processing"
            
            if bonk_finished and pump_finished:
                header = "🎉 <b>All Workers Complete</b>"
                footer = "\n🚀 <i>Triggering wallet processing...</i>"
            else:
                header = "🔄 <b>Worker Status Update</b>"
                footer = "\n⏳ <i>Waiting for all workers to complete...</i>"
            
            message = f"""
{header}

🟠 <b>BONK Worker:</b> {bonk_status}
🔵 <b>PUMP Worker:</b> {pump_status}{footer}
            """.strip()
            
            return await self.send_message(message)
            
        except Exception as e:
            telegram_logger.error(f"❌ Error sending coordination update: {e}", exc_info=True)
            return False

# Convenience functions for direct usage
notifier = TelegramNotifier()

async def send_telegram_message(message: str, parse_mode: str = "HTML") -> bool:
    """
    Send a simple message to Telegram
    
    Args:
        message: Message to send
        parse_mode: Parsing mode (HTML, Markdown, or None)
        
    Returns:
        bool: True if successful, False otherwise
    """
    return await notifier.send_message(message, parse_mode)

async def send_telegram_alert(title: str, message: str, level: str = "INFO") -> bool:
    """
    Send an alert to Telegram
    
    Args:
        title: Alert title
        message: Alert message
        level: Alert level
        
    Returns:
        bool: True if successful, False otherwise
    """
    return await notifier.send_alert(title, message, level)

async def send_telegram_error(error: str, context: str = None) -> bool:
    """
    Send an error alert to Telegram
    
    Args:
        error: Error message
        context: Additional context
        
    Returns:
        bool: True if successful, False otherwise
    """
    return await notifier.send_error_alert(error, context)

async def send_token_report(stats: Dict[str, Any]) -> bool:
    """
    Send token processing report to Telegram
    
    Args:
        stats: Processing statistics
        
    Returns:
        bool: True if successful, False otherwise
    """
    return await notifier.send_token_processing_report(stats)

async def send_wallet_report(wallet_count: int, processing_time: float = None) -> bool:
    """
    Send wallet processing report to Telegram
    
    Args:
        wallet_count: Number of wallets processed
        processing_time: Processing time in seconds
        
    Returns:
        bool: True if successful, False otherwise
    """
    return await notifier.send_wallet_processing_report(wallet_count, processing_time)

async def send_system_status_report(services: Dict[str, str]) -> bool:
    """
    Send system status report to Telegram
    
    Args:
        services: Dictionary of service statuses
        
    Returns:
        bool: True if successful, False otherwise
    """
    return await notifier.send_system_status(services)

async def send_performance_report(rps: float, efficiency: float, 
                                total_requests: int, processing_time: float) -> bool:
    """
    Send performance report to Telegram
    
    Args:
        rps: Requests per second
        efficiency: Efficiency percentage
        total_requests: Total requests
        processing_time: Processing time
        
    Returns:
        bool: True if successful, False otherwise
    """
    return await notifier.send_performance_report(rps, efficiency, total_requests, processing_time)

async def send_coordination_status(bonk_finished: bool, pump_finished: bool) -> bool:
    """
    Send coordination status to Telegram
    
    Args:
        bonk_finished: BONK worker status
        pump_finished: PUMP worker status
        
    Returns:
        bool: True if successful, False otherwise
    """
    return await notifier.send_coordination_update(bonk_finished, pump_finished)

# Test function
async def test_telegram_notifications():
    """Test Telegram notifications functionality"""
    try:
        # Test basic message
        await send_telegram_message("🧪 <b>Test Message</b>\n\nTelegram notifications are working!")
        
        # Test alert
        await send_telegram_alert("Test Alert", "This is a test alert message", "INFO")
        
        # Test token report
        test_stats = {
            'total_processed': 100,
            'good_tokens': 75,
            'bad_tokens': 20,
            'already_processed': 5,
            'good_pump_tokens': 40,
            'good_bonk_tokens': 35
        }
        await send_token_report(test_stats)
        
        print("✅ Test messages sent to Telegram")
        
    except Exception as e:
        print(f"❌ Test failed: {e}")

if __name__ == "__main__":
    # Run test if executed directly
    asyncio.run(test_telegram_notifications())