from __future__ import annotations

from functools import lru_cache
from pathlib import Path
from urllib.parse import quote_plus

from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict

# supply_infra/config.py -> project root; avoid depending on process cwd
_PROJECT_ROOT = Path(__file__).resolve().parent.parent
_ENV_FILE = _PROJECT_ROOT / ".env"


class InfraSettings(BaseSettings):
    """Shared infrastructure settings."""

    model_config = SettingsConfigDict(
        env_file=str(_ENV_FILE),
        env_file_encoding="utf-8",
        extra="ignore",
    )

    # MySQL
    mysql_host: str = Field(default="127.0.0.1", alias="MYSQL_HOST")
    mysql_port: int = Field(default=3306, alias="MYSQL_PORT")
    mysql_user: str = Field(default="root", alias="MYSQL_USER")
    mysql_password: str = Field(default="", alias="MYSQL_PASSWORD")
    mysql_database: str = Field(default="supply_agent", alias="MYSQL_DATABASE")
    mysql_pool_size: int = Field(default=5, alias="MYSQL_POOL_SIZE")
    mysql_echo: bool = Field(default=False, alias="MYSQL_ECHO")

    # ODPS (MaxCompute)
    odps_access_id: str = Field(default="", alias="ODPS_ACCESS_ID")
    odps_access_key: str = Field(default="", alias="ODPS_ACCESS_KEY")
    odps_project: str = Field(default="", alias="ODPS_PROJECT")
    odps_endpoint: str = Field(
        default="https://service.cn.maxcompute.aliyun.com/api",
        alias="ODPS_ENDPOINT",
    )

    # Scheduler
    scheduler_timezone: str = Field(default="Asia/Shanghai", alias="SCHEDULER_TIMEZONE")
    scheduler_enabled: bool = Field(default=True, alias="SCHEDULER_ENABLED")

    # Aliyun OSS (agent run log publishing)
    aliyun_oss_access_key_id: str = Field(default="", alias="ALIYUN_OSS_ACCESS_KEY_ID")
    aliyun_oss_access_key_secret: str = Field(default="", alias="ALIYUN_OSS_ACCESS_KEY_SECRET")
    aliyun_oss_region: str = Field(default="cn-hangzhou", alias="ALIYUN_OSS_REGION")
    aliyun_oss_bucket: str = Field(default="art-pubbucket", alias="ALIYUN_OSS_BUCKET")
    aliyun_oss_root_prefix: str = Field(default="supply_agent", alias="ALIYUN_OSS_ROOT_PREFIX")
    aliyun_oss_manual_log_prefix: str = Field(
        default="supply_agent/manual_logs",
        alias="ALIYUN_OSS_MANUAL_LOG_PREFIX",
    )
    aliyun_oss_public_base_url: str = Field(
        default="http://rescdn.yishihui.com",
        alias="ALIYUN_OSS_PUBLIC_BASE_URL",
    )
    log_oss_upload_enabled: bool = Field(default=True, alias="LOG_OSS_UPLOAD_ENABLED")

    @property
    def mysql_url(self) -> str:
        user = quote_plus(self.mysql_user)
        password = quote_plus(self.mysql_password)
        return (
            f"mysql+pymysql://{user}:{password}"
            f"@{self.mysql_host}:{self.mysql_port}/{self.mysql_database}"
            f"?charset=utf8mb4"
        )


@lru_cache
def get_infra_settings() -> InfraSettings:
    return InfraSettings()
