from enum import StrEnum

from pydantic import Field, PostgresDsn, computed_field
from pydantic_settings import BaseSettings, SettingsConfigDict
from advanced_alchemy.extensions.litestar import (
    SQLAlchemyAsyncConfig,
)


class DuplicateScope(StrEnum):
    """How widely an incoming file is compared against what is already stored."""

    LIBRARY = "library"
    """Only files in the library being uploaded to count as duplicates."""

    GLOBAL = "global"
    """A file already held by any library counts as a duplicate."""

    OFF = "off"
    """No duplicate detection at all."""


class Settings(BaseSettings):
    version: str = Field("0.0.1")
    project_name: str = Field("chitai")

    # Database settings
    postgres_db: str = Field("chitai")
    postgres_user: str = Field("chitai_user")
    postgres_password: str = Field("chitai_password")
    postgres_host: str = Field("localhost")
    postgres_port: str = Field("5432")
    postgres_echo: bool = Field(False)
    postgres_scheme: str = "postgresql+asyncpg"

    # Debug settings
    api_debug: bool = Field(False)

    # JWT token secret
    token_secret: str = Field("secret")

    # Defaut library
    default_library_name: str = Field("Books")
    default_library_path: str = Field("./books")

    # Path to book covers
    book_cover_path: str = Field("./covers")

    # Path to consume directory
    consume_path: str = Field("./consume")

    # Duplicate detection
    duplicate_scope: DuplicateScope = Field(DuplicateScope.LIBRARY)

    # Where the consume watcher parks files it refused as duplicates. Must sit
    # outside `consume_path`, or the watcher picks them straight back up and
    # tries to resolve the directory name as a library slug.
    duplicate_path: str = Field("./duplicates")

    @computed_field
    @property
    def postgres_uri(self) -> PostgresDsn:
        return PostgresDsn(
            f"{self.postgres_scheme}://{self.postgres_user}:{self.postgres_password}"
            f"@{self.postgres_host}:{self.postgres_port}/{self.postgres_db}"
        )

    model_config = SettingsConfigDict(
        env_prefix="chitai_", env_file=".env", validate_default=False, extra="ignore"
    )

    @property
    def alchemy_config(self) -> SQLAlchemyAsyncConfig:
        from chitai.database.config import config

        return config


settings = Settings()  # type: ignore
