from __future__ import annotations

import logging
import os
import sys
from pathlib import Path

from pydantic import AliasChoices, Field, model_validator
from pydantic_settings import BaseSettings

_INSECURE_DEFAULTS = {
    "epochler_password": "changeme",
    "epochler_secret_key": "dev-secret-key-change-in-production",
}


class Settings(BaseSettings):
    anthropic_api_key: str = ""
    gemini_api_key: str = ""

    epochler_password: str = Field(
        default="changeme",
        validation_alias=AliasChoices("EPOCHLER_PASSWORD"),
    )
    epochler_secret_key: str = Field(
        default="dev-secret-key-change-in-production",
        validation_alias=AliasChoices("EPOCHLER_SECRET_KEY"),
    )
    jwt_algorithm: str = "HS256"
    jwt_expire_minutes: int = 60 * 24 * 7  # 1 week

    data_dir: Path = Path(__file__).resolve().parent.parent / "data"
    workspace_root: Path | None = None

    anthropic_model: str = "claude-opus-4-6"
    anthropic_planner_model: str = "claude-sonnet-4-6"
    gemini_model: str = "gemini-3-flash-preview"
    gemini_lite_model: str = "gemini-3.1-flash-lite-preview"

    cors_origins: str = "http://localhost:5173,http://localhost:3000"

    model_config = {"env_file": ".env", "env_file_encoding": "utf-8", "extra": "ignore"}

    @model_validator(mode="after")
    def _reject_insecure_defaults(self) -> Settings:
        for field, insecure_value in _INSECURE_DEFAULTS.items():
            if getattr(self, field) == insecure_value:
                logging.critical(
                    "FATAL: '%s' is still set to its default value. "
                    "Set it in your .env file or as an environment variable before starting Epochler.",
                    field.upper(),
                )
                sys.exit(1)
        return self


_settings: Settings | None = None


def get_settings() -> Settings:
    global _settings
    if _settings is None:
        env_path = Path(__file__).resolve().parent.parent / ".env"
        if env_path.exists():
            os.environ.setdefault("ENV_FILE", str(env_path))
        _settings = Settings(_env_file=str(env_path) if env_path.exists() else None)
    return _settings
