"""
Configuration for the churn prediction ML pipeline.
Reads database credentials from Laravel's .env file.
"""

import os
from pathlib import Path

try:
    from dotenv import load_dotenv
except ModuleNotFoundError:
    # Optional dependency: pipeline can still run when env is injected by Laravel.
    def load_dotenv(*_args, **_kwargs):
        return False

# Load Laravel .env
_env_path = Path(__file__).resolve().parent.parent / '.env'
load_dotenv(_env_path)


def _parse_db_url():
    """Parse DATABASE_URL if available, otherwise use individual vars."""
    url = os.getenv('DATABASE_URL')
    if url:
        # postgres://user:pass@host:port/dbname
        from urllib.parse import urlparse
        parsed = urlparse(url)
        return {
            'host': parsed.hostname,
            'port': parsed.port or 5432,
            'dbname': parsed.path.lstrip('/'),
            'user': parsed.username,
            'password': parsed.password,
        }

    return {
        'host': os.getenv('DB_HOST', '127.0.0.1'),
        'port': int(os.getenv('DB_PORT', 5432)),
        'dbname': os.getenv('DB_DATABASE', 'sms_admin'),
        'user': os.getenv('DB_USERNAME', 'postgres'),
        'password': os.getenv('DB_PASSWORD', ''),
    }


DB_CONFIG = _parse_db_url()


CLICKHOUSE_CONFIG = {
    'scheme': os.getenv('CLICKHOUSE_SCHEME', 'http'),
    'host': os.getenv('CLICKHOUSE_HOST', ''),
    'port': int(os.getenv('CLICKHOUSE_PORT', 8123)),
    'database': os.getenv('CLICKHOUSE_DATABASE', 'clickhouse'),
    'username': os.getenv('CLICKHOUSE_USERNAME', 'default'),
    'password': os.getenv('CLICKHOUSE_PASSWORD', ''),
    'timeout_seconds': int(os.getenv('CLICKHOUSE_TIMEOUT_SECONDS', 120)),
}

CHURN_FEATURE_STORE_TABLE = os.getenv('AI_CHURN_FEATURE_STORE_TABLE', 'churn_feature_store')
CHURN_MODEL_REGISTRY_TABLE = os.getenv('AI_CHURN_MODEL_REGISTRY_TABLE', 'churn_model_registry')
CHURN_PREDICTIONS_TABLE = os.getenv('AI_CHURN_PREDICTIONS_TABLE', 'churn_predictions')
CHURN_TRAINING_LABELS_TABLE = os.getenv('AI_CHURN_TRAINING_LABELS_TABLE', 'churn_training_labels')

# Model storage
MODEL_DIR = Path(__file__).resolve().parent / 'models'
MODEL_DIR.mkdir(exist_ok=True)

# Default app_id (can be overridden via CLI --app-id)
DEFAULT_APP_ID = int(os.getenv('CHURN_APP_ID', '0'))

# Phase 1 feature columns (no content_watched)
PHASE1_FEATURE_COLUMNS = [
    # Demographics
    'customer_tenure_days',
    'days_since_last_login',
    # Subscription behavior
    'total_subscriptions',
    'active_subscription_count',
    'days_until_expiry',
    'auto_renew_enabled',
    'subscription_price',
    'failed_payment_count_30d',
    'failed_payment_count_90d',
    'payment_failure_rate',
    'subscription_gap_days',
    'has_downgraded',
    # Financial
    'total_revenue',
    'avg_order_value',
    'revenue_trend',
    'coupon_user',
    # Behavioral
    'renewal_rate',
    'has_ever_churned',
    'churns_count',
]

# Phase 2 adds these (tbl_content_watched) — not used yet
PHASE2_FEATURE_COLUMNS = [
    'watch_count_7d',
    'watch_count_30d',
    'watch_count_90d',
    'total_watch_duration_30d',
    'avg_watch_duration',
    'days_since_last_watch',
    'watch_count_decline_pct',
    'duration_decline_pct',
    'unique_categories_30d',
    'binge_sessions_30d',
    'is_currently_watching',
    'content_type_diversity',
]

# Active feature set for current phase
FEATURE_COLUMNS = PHASE1_FEATURE_COLUMNS

# Minimum labeled samples required to train an app-specific model.
# Apps below this threshold fall back to the global model.
MIN_TRAINING_SAMPLES = 200

# Model filenames
GLOBAL_MODEL_FILENAME = 'lgbm_global.pkl'

def app_model_filename(app_id: int) -> str:
    """Return the pickle filename for an app-specific model."""
    return f'lgbm_model_app_{app_id}.pkl'
