# app/modules/loyalty/config.py
"""
Module configuration.

Environment-based configuration using Pydantic Settings.
Settings are loaded from environment variables with LOYALTY_ prefix.

Example:
    LOYALTY_DEFAULT_COOLDOWN_MINUTES=15
    LOYALTY_MAX_DAILY_STAMPS=5
    LOYALTY_GOOGLE_ISSUER_ID=3388000000012345678

Usage:
    from app.modules.loyalty.config import config
    cooldown = config.default_cooldown_minutes
"""
import os

from pydantic import field_validator
from pydantic_settings import BaseSettings


class ModuleConfig(BaseSettings):
    """Configuration for loyalty module."""

    # Default anti-fraud settings
    default_cooldown_minutes: int = 15
    max_daily_stamps: int = 5
    pin_max_failed_attempts: int = 5
    pin_lockout_minutes: int = 30

    # Points configuration
    default_points_per_euro: int = 10  # 10 points per euro spent

    # Apple Wallet
    apple_pass_type_id: str | None = None
    apple_team_id: str | None = None
    apple_wwdr_cert_path: str | None = None  # Apple WWDR certificate
    apple_signer_cert_path: str | None = None  # Pass signing certificate
    apple_signer_key_path: str | None = None  # Pass signing key

    # Google Wallet
    # In production the service account JSON lives at
    # ~/apps/orion/google-wallet-sa.json (app user, mode 600).
    google_issuer_id: str | None = None
    google_service_account_json: str | None = None  # Path to service account JSON
    google_wallet_origins: list[str] = []  # Allowed origins for save-to-wallet JWT
    default_logo_url: str = "https://rewardflow.lu/static/modules/loyalty/shared/img/default-logo-200.png"

    # QR code settings
    qr_code_size: int = 300  # pixels

    model_config = {"env_prefix": "LOYALTY_", "env_file": ".env", "extra": "ignore"}

    @field_validator("google_service_account_json")
    @classmethod
    def google_sa_path_must_exist(cls, v: str | None) -> str | None:
        """
        When a Google Wallet service account JSON path is configured, it must
        point to a file that exists and is readable. Fails fast at import time
        rather than letting the first wallet API call blow up at runtime.

        A leading ``~`` is expanded so deployments can use ``~/apps/orion/...``
        without hardcoding the home directory.
        """
        if v is None or v == "":
            return v
        expanded = os.path.expanduser(v)
        if not os.path.isfile(expanded):
            raise ValueError(
                f"LOYALTY_GOOGLE_SERVICE_ACCOUNT_JSON points to "
                f"'{expanded}' but no file exists at that path"
            )
        if not os.access(expanded, os.R_OK):
            raise ValueError(
                f"LOYALTY_GOOGLE_SERVICE_ACCOUNT_JSON file at "
                f"'{expanded}' is not readable by the current process"
            )
        return expanded

    @property
    def is_google_wallet_enabled(self) -> bool:
        """True when both an issuer ID and a readable service account file are set."""
        return bool(self.google_issuer_id and self.google_service_account_json)

    @property
    def is_apple_wallet_enabled(self) -> bool:
        """True when all Apple Wallet credentials are configured.

        Phase 9 will add file-existence validators for the Apple cert paths;
        for now this just checks that all five env vars are populated, which
        gates the storefront UI from offering Apple Wallet when the platform
        cannot actually generate passes.
        """
        return bool(
            self.apple_pass_type_id
            and self.apple_team_id
            and self.apple_wwdr_cert_path
            and self.apple_signer_cert_path
            and self.apple_signer_key_path
        )


# Export for auto-discovery
config_class = ModuleConfig
config = ModuleConfig()
