"""
Configuration management for mycopunk CLI.
"""

import os
from pathlib import Path
from typing import Optional, Any

import yaml
from dotenv import load_dotenv


def get_project_root() -> Path:
    """Find the project root (directory containing designs/)."""
    current = Path.cwd()
    while current != current.parent:
        if (current / "designs").is_dir():
            return current
        current = current.parent
    return Path.cwd()


PROJECT_ROOT = get_project_root()
CONFIG_DIR = PROJECT_ROOT / "config"


class Config:
    """Configuration manager for mycopunk."""

    _instance: Optional["Config"] = None

    def __new__(cls) -> "Config":
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance._initialized = False
        return cls._instance

    def __init__(self) -> None:
        if self._initialized:
            return

        self._initialized = True
        self._products: dict = {}
        self._pricing: dict = {}

        # Load environment variables
        env_path = CONFIG_DIR / ".env"
        if env_path.exists():
            load_dotenv(env_path)

        # Load product configuration
        products_path = CONFIG_DIR / "products.yaml"
        if products_path.exists():
            with open(products_path) as f:
                self._products = yaml.safe_load(f) or {}

        # Load pricing configuration
        pricing_path = CONFIG_DIR / "pricing.yaml"
        if pricing_path.exists():
            with open(pricing_path) as f:
                self._pricing = yaml.safe_load(f) or {}

    @property
    def env(self) -> str:
        """Get current environment (development/production)."""
        return os.getenv("MYCOPUNK_ENV", "development")

    @property
    def is_production(self) -> bool:
        """Check if running in production mode."""
        return self.env == "production"

    @property
    def debug(self) -> bool:
        """Check if debug mode is enabled."""
        return os.getenv("DEBUG", "false").lower() == "true"

    @property
    def default_provider(self) -> str:
        """Get default POD provider."""
        return os.getenv("DEFAULT_PROVIDER", "prodigi")

    # API Keys

    @property
    def printful_token(self) -> Optional[str]:
        """Get Printful API token."""
        return os.getenv("PRINTFUL_API_TOKEN")

    @property
    def prodigi_key(self) -> Optional[str]:
        """Get Prodigi API key (sandbox or live based on env)."""
        if self.is_production:
            return os.getenv("PRODIGI_API_KEY_LIVE")
        return os.getenv("PRODIGI_API_KEY_SANDBOX")

    @property
    def stripe_key(self) -> Optional[str]:
        """Get Stripe secret key."""
        return os.getenv("STRIPE_SECRET_KEY")

    # Product Configuration

    def get_product_config(self, product_type: str, size: str = "small") -> dict:
        """Get product configuration by type and size."""
        type_config = self._products.get(product_type, {})
        return type_config.get(size, {})

    def get_provider_sku(
        self,
        product_type: str,
        size: str,
        provider: str
    ) -> Optional[str]:
        """Get provider-specific SKU for a product."""
        config = self.get_product_config(product_type, size)
        providers = config.get("providers", {})
        provider_config = providers.get(provider, {})
        return provider_config.get("sku")

    def get_base_cost(
        self,
        product_type: str,
        size: str,
        provider: str,
        variant: Optional[str] = None
    ) -> float:
        """Get base cost for a product from provider."""
        config = self.get_product_config(product_type, size)
        providers = config.get("providers", {})
        provider_config = providers.get(provider, {})

        base_cost = provider_config.get("base_cost", 0)

        # Handle size-specific pricing (apparel)
        if isinstance(base_cost, dict) and variant:
            return base_cost.get(variant, 0)

        return float(base_cost) if not isinstance(base_cost, dict) else 0

    # Pricing

    def calculate_retail_price(
        self,
        base_cost: float,
        product_type: str
    ) -> float:
        """Calculate retail price from base cost with markup."""
        pricing = self._pricing or self._products.get("pricing", {})
        rules = pricing.get("rules", {})
        type_rules = rules.get(product_type, {})

        markup = type_rules.get("markup", pricing.get("default_markup", 2.0))
        minimum = type_rules.get("minimum_price", 0)

        calculated = base_cost * markup
        price = max(calculated, minimum)

        # Apply rounding
        rounding = pricing.get("rounding", "nearest_99")
        if rounding == "nearest_99":
            price = round(price) - 0.01
        elif rounding == "nearest_50":
            price = round(price * 2) / 2

        return max(price, minimum)


# Singleton accessor
def get_config() -> Config:
    """Get the configuration singleton."""
    return Config()
