import os
from dotenv import load_dotenv
load_dotenv()
from telegram import Bot
from telegram.ext import Application
from bot.core.base import Base
import inspect
from bot.utils import root_path,FileFinder
from telegram.ext import PicklePersistence
import importlib
from pathlib import Path
import logging

class TelegramBot:
    def __init__(
            self,
            token: str = None,
            admins: list[int] = None
    ):
            token = token or os.environ.get('BOT_TOKEN')
            if admins is None:
                admins: list = os.getenv('ADMIN_IDS').split(' ')
                admins = list(map(lambda x: int(x.strip()), admins))
            persistence = PicklePersistence(filepath="bot_persistence",update_interval=5)
            proxy = os.getenv('PROXY')
            proxy_enable = bool(int(os.getenv('PROXY_ENABLE')))
            if proxy_enable:
                self.app = Application.builder().token(token).proxy(proxy).persistence(persistence).build()
            else:
                self.app = Application.builder().token(token).persistence(persistence).build()
            self.bot:Bot = self.app.bot
            self.admins = admins
            self._node_dir=os.getenv('PANEL_DIR')+'/roles'
            self.app.add_error_handler(self.error_handler)
    async def error_handler(self,update, context):
        # ثبت اطلاعات خطا در لاگ
        logging.error("Exception occurred", exc_info=context.error)

    def autodiscover(self):
        path=root_path()
        ff=FileFinder(f"{path}/{self._node_dir}")
        # Get all Python files in the nodes directory
        python_files = ff.find_by_extension('.py')
        for file_path in python_files:
            # Convert file path to module path
            relative_path = Path(file_path).relative_to(path)
            module_path = str(relative_path).replace('/', '.').replace('.py', '')
            # Load the module
            module = self.__load_module_from_str(module_path)

            if module:
                # Find all Base subclasses in the module
                subclasses_in_module = [
                    cls for name, cls in inspect.getmembers(module, inspect.isclass)
                    if issubclass(cls, Base) and cls is not Base
                ]
                # Initialize and process each subclass
                for cls in subclasses_in_module:
                    print(f"Loading panel {cls.__name__}")
                    instance:Base = cls()
                    instance.build(self.bot,self.admins)
                    for handler in instance._handlers:
                        self.app.add_handler(handler)

    async def stop(self):
        """Stops the setting and cleans up resources"""
        if self.app:
            await self.app.stop()
            await self.app.shutdown()

    def run(self):
        self.autodiscover()
        self.app.run_polling()


    def __load_module_from_str(self,module_path: str):
        """
        Load a module from a string path.
        Example: 'nodes.admin.commands' will load the commands module
        """
        try:

            return importlib.import_module(module_path)
        except ImportError as e:
            logging.error(e)
            return None