import os

from pathlib import Path
from random import choice
from string import ascii_lowercase, digits, ascii_uppercase


class ConfigGen:
    def __init__(self):
        self.__db_connection_string: str = "sqlite"
        self.__db_name: str = None
        self.__db_user: str = None
        self.__db_password: str = None
        self.__db_host: str = None
        self.__db_port: str = None
        self.__secret_key: str = self.create_secret_key()
        self.__allowed_hosts: list = None
        self.__debug: bool = True
        self.__root_dir: Path = Path.cwd()  # Use o diretório de trabalho atual

    @staticmethod
    def create_hexadigits():
        string = ascii_lowercase + digits + ascii_uppercase
        return "".join(choice(string) for _ in range(8))

    @staticmethod
    def create_secret_key():
        pontuaction = "!@#$+&-"
        string = ascii_lowercase + digits + ascii_uppercase + pontuaction
        return "".join(choice(string) for _ in range(64))

    def create_files_default(self):
        """Creates default .env, settings.py and logger.py files in the project root."""
        self._create_envfile_default()
        self._create_settings_default()
        self._create_logger_file()

    def _create_envfile_default(self):
        """Creates a default .env file in the root directory."""
        db_name = self.create_hexadigits()
        self.__db_name = f"{db_name}.sqlite3"

        with open(self.__root_dir / ".env", "w", encoding="utf-8") as env_file:
            env_file.write(
                f"""# .env file generated by ConfigGen
DB_CONNECTION_STRING='{self.__db_connection_string}'
DB_NAME='{self.__db_name}'
"""
            )

    def _create_settings_default(self):
        """Creates a default settings.py file in the root directory."""
        with open(self.__root_dir / "settings.py", "w", encoding="utf-8") as pyfile:
            pyfile.write(
                """import os
from dotenv import load_dotenv


class Settings:
    load_dotenv(".env")
    DB_CONNECTION_STRING: str = os.getenv("DB_CONNECTION_STRING")
    DB_NAME: str = os.getenv("DB_NAME")
    DB_URL: str = f"{DB_CONNECTION_STRING}:///{DB_NAME}"
settings: Settings = Settings()
"""
            )

    def _create_logger_file(self):
        """Creates a default logger.py file in the root directory."""
        with open(self.__root_dir / "logger.py", "w", encoding="utf-8") as pyfile:
            pyfile.write(
                """import logging
import os
from rich.logging import RichHandler
from pathlib import Path
from datetime import datetime


def set_logger():
    os.makedirs(os.path.join(Path.cwd(), "logs"), exists_ok=True)
    logging.basicConfig(
        level=logging.DEBUG,
        format="%(asctime)s | %(levelname)-8s | %(message)s",
        datefmt="[%Y-%m-%d %H:%M:%S]",
        handlers=[
            RichHandler(rich_tracebacks=True),
            logging.FileHandler(
                f"{os.path.join(Path.cwd(), 'logs', f'{datetime.now().strftime('%Y-%m-%d')}.log')}",
                enconding="utf-8",
            ),
        ]
    )
    return logging.getLogger(__name__)
logger = set_logger()
"""
            )

    def _create_basic_fastapi_settings(self):
        """Creates basic settings for the fastapi app"""
        os.makedirs(os.path.join(self.__root_dir, "src"), exists_ok=True)
        os.makedirs(os.path.join(self.__root_dir, "src", "core"), exists_ok=True)
        with open(
            os.path.join(self.__root_dir, "src", "core", "settings.py"),
            "w",
            encoding="utf-8",
        ) as pyfile:
            pyfile.write(
                """import os
from pydantic import BaseModel
from dotenv import load_dotenv
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent


class Settings(BaseModel):
    load_dotenv(os.path.join(BASE_DIR, ".env"))
    ALGORITHM: str = os.getenv("ALGORITHM")
    ACCESS_TOKEN_EXPIRE_MINUTES: int = os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES")
    APP_NAME: str = os.getenv("APP_NAME")
    APP_VERSION: str = os.getenv("APP_VERSION")
    API_PREFIX: str = os.getenv("API_PREFIX")
    DB_CONNECTION_STRING: str = os.getenv("DB_CONNECTION_STRING")
    DB_NAME: str = os.getenv("DB_NAME")
    DB_PASSWORD: str = os.getenv("DB_PASSWORD")
    DB_USER: str = os.getenv("DB_USER")
    DB_HOST: str = os.getenv("DB_HOST")
    DB_PORT: str = os.getenv("DB_PORT")
    DB_URL: str = f"{DB_CONNECTION_STRING}://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}"
    TOKEN: str = os.getenv("TOKEN")
settings: Settings = Settings()
"""
            )

    def _create_envfile_fastapi(self):
        """Creates a .env file for the fastapi app"""
        with open(
            os.path.join(self.__root_dir, ".env"), "w", encoding="utf-8"
        ) as env_file:
            env_file.write(
                f"""# .env file generated by ConfigGen
ALGORITHM='HS256'
ACCESS_TOKEN_EXPIRE_MINUTES=60*24*7
APP_NAME='FastAPI'
APP_VERSION='1.0.0'
API_PREFIX='/api/v1'
DB_CONNECTION_STRING='asyncpg+postgresql'
DB_NAME='{self.__db_name}'
DB_USER='postgres'
DB_PASSWORD='postgres'
DB_HOST='localhost'
DB_PORT='5432'
TOKEN='{self.__secret_key}'
"""
            )

    def create_fastapi_files(self):
        """Creates default files for the fastapi app"""
        self._create_basic_fastapi_settings()
        self._create_envfile_fastapi()
