from pathlib import Path
from backend.core.settings.db_providers import AbstractDBProvider, SQLiteProvider
from pydantic_settings import BaseSettings # type: ignore


def determine_secrets(production: bool) -> str:
  if not production:
    return "shh-secret-test-key"

  return "1d00e664fb3b07aff5a191755ea72f9c4bc85a3f36868308d0b2c417aed3419e"

def determine_cookie(production: bool) -> str:
  if not production:
    return "logcook"

  return "7fo24CMyIc"

class AppSettings(BaseSettings):
  PRODUCTION: bool
  TESTING: bool
  BASE_URL: str = "http://localhost:8080"
  """trailing slashes are trimmed (ex. `http://localhost:8080/` becomes ``http://localhost:8080`)"""

  HOST_IP: str = "*"

  API_HOST: str = "0.0.0.0"
  API_PORT: int = 9000
  API_DOCS: bool = True

  ALLOW_SIGNUP: bool = False

  SECRET: str
  COOKIE_KEY: str
  EXP_TOKEN: int = 30
  """in minutes, default is 30 minutes"""
  EXP_REFRESH: int = 7
  """in days, default is 7 days"""

  LOG_CONFIG_OVERRIDE: Path | None = None
  """path to custom logging configuration file"""

  LOG_LEVEL: str = "info"
  """corresponds to standard Python log levels"""

  @property
  def DOCS_URL(self) -> str | None:
    return "/docs" if self.API_DOCS else None

  @property
  def REDOC_URL(self) -> str | None:
    return "/redoc" if self.API_DOCS else None

  # ===============================================
  # Database Configuration

  DB_PROVIDER: AbstractDBProvider | None = None

  @property
  def DB_URL(self) -> str | None:
    return self.DB_PROVIDER.db_url if self.DB_PROVIDER else None

  @property
  def DB_URL_PUBLIC(self) -> str | None:
    return self.DB_PROVIDER.db_url_public if self.DB_PROVIDER else None

def app_settings_constructor(data_dir: Path, production: bool, env_file: Path, env_encoding="utf-8") -> AppSettings:
  """
  app_settings_constructor is a factory function that returns an AppSettings object. It is used to inject the
  required dependencies into the AppSettings object and nested child objects. AppSettings should not be substantiated
  directly, but rather through this factory function.
  """
  app_settings = AppSettings(
    _env_file=env_file,  # type: ignore
    _env_file_encoding=env_encoding,  # type: ignore
    **{"SECRET": determine_secrets(production), 'COOKIE_KEY': determine_cookie(production)},
  )

  app_settings.DB_PROVIDER = SQLiteProvider(data_dir=data_dir)

  return app_settings