from utils.telegram import Telegram
from utils.logger import logger
from typing import Optional, Dict
import asyncio, glob, random, os
from pathlib import Path


class SpamBot:
    def __init__(self, send_request: bool = True, count: int = 0) -> None:
        os.makedirs('free_sessions', exist_ok=True)
        os.makedirs('success_sessions', exist_ok=True)
        os.makedirs('valid_sessions', exist_ok=True)
        os.makedirs('invalid_sessions', exist_ok=True)
        
        self.send_request = send_request
        self.count = count
    
    
    def get_proxy(self) -> Optional[str]:
        try:
            with open('utils/proxies.txt', 'r', encoding='utf-8') as f:
                proxies = [line.strip() for line in f if line.strip() and not line.strip().startswith('#')]
            return random.choice(proxies) if proxies else None
        except FileNotFoundError:
            logger.warning('<red>[-]</red> utils/proxies.txt not found. Continuing without proxies.')
            return None


    def parse_proxy_line(self, line: Optional[str]) -> Optional[dict]:
        if line:
            parts = line.split(':')
            try:
                if len(parts) == 2:
                    return {'proxy_type': 'socks5', 'addr': parts[0], 'port': int(parts[1])}
                elif len(parts) >= 4:
                    return {'proxy_type': 'socks5', 'addr': parts[0], 'port': int(parts[1]),
                            'username': parts[2], 'password': parts[3]}
                else:
                    return None
            except Exception:
                return None
        return None
    
    
    async def run(self) -> bool:
        try:
            accounts = glob.glob('valid_sessions/*.session')
            if len(accounts) == 0:
                return logger.error(f'<red>[-]</red> There are no sessions, upload your sessions in (<yellow>valid_sessions</yellow>)')
            
            logger.info('<green>[+]</green> The process will start in a few seconds ...')
            
            for account in random.sample(accounts, self.count) if self.count > 0 else accounts:
                phone_number = Path(account).stem
                
                logger.info('----------------------------------------')
                logger.info(f'<green>[+]</green> Phone number: <yellow>{phone_number}</yellow>')
                
                proxy = self.parse_proxy_line(self.get_proxy())
                logger.info(f"<green>[+]</green> Proxy: {proxy.get('addr')}:{proxy.get('port')}" + (f":{proxy.get('username')}:{proxy.get('password')}") if proxy and proxy.get('username') and proxy.get('password') else '') if proxy else logger.info(f'<green>[+]</green> Proxy: None')
                
                telegram = Telegram(phone_number=phone_number, proxy=proxy)
                
                logger.info(f'<green>[+]</green> Sending request to <yellow>@Spambot</yellow>')
                response = await telegram.check_spam(send_request=self.send_request)
                
                if response:
                    logger.info(f'<green>[+]</green> Account is free in (<yellow>@SpamBot</yellow>) bot')
                    
                    if self.send_request == False:
                        try:
                            if os.path.exists(f'valid_sessions/{phone_number}.session'):
                                os.rename(f'valid_sessions/{phone_number}.session', f'free_sessions/{phone_number}.session')
                            
                            if os.path.exists(f'valid_sessions/{phone_number}.json'):
                                os.rename(f'valid_sessions/{phone_number}.json', f'free_sessions/{phone_number}.json')
                            
                            logger.info(f'<green>[+]</green> Session and JSON files for <yellow>{phone_number}</yellow> moved to (<yellow>free_sessions</yellow>)')
                        
                        except Exception as move_err:
                            logger.error(f'<red>[-]</red> Failed to move session or json for {phone_number}: {move_err}')
                    
                    else:
                        try:
                            if os.path.exists(f'valid_sessions/{phone_number}.session'):
                                os.rename(f'valid_sessions/{phone_number}.session', f'success_sessions/{phone_number}.session')
                            
                            if os.path.exists(f'valid_sessions/{phone_number}.json'):
                                os.rename(f'valid_sessions/{phone_number}.json', f'success_sessions/{phone_number}.json')
                            
                            logger.info(f'<green>[+]</green> Session and JSON files for <yellow>{phone_number}</yellow> moved to (<yellow>success_sessions</yellow>)')
                        
                        except Exception as move_err:
                            logger.error(f'<red>[-]</red> Failed to move session or json for {phone_number}: {move_err}')
                
                else:
                    logger.error(f'<red>[-]</red> Account is spam in (<yellow>@SpamBot</yellow>) bot')
        
        except Exception as error:
            logger.error(f'<red>[-]</red> Spam.run -> {error}')
            return False


async def main() -> None:
    spam = SpamBot(send_request=True, count=0)
    await spam.run()

asyncio.run(main())