"""HeyLead config management — ~/.heylead/config.json."""

from __future__ import annotations

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

from . import constants

logger = logging.getLogger(__name__)


def _heylead_home() -> Path:
    """Return the HeyLead home directory (~/.heylead)."""
    return Path.home() / constants.HEYLEAD_DIR_NAME


def ensure_dirs() -> Path:
    """Create all required directories and return the home path."""
    home = _heylead_home()
    (home / constants.DB_DIR).mkdir(parents=True, exist_ok=True)
    (home / constants.AUTH_DIR).mkdir(parents=True, exist_ok=True)
    (home / constants.LOG_DIR).mkdir(parents=True, exist_ok=True)
    return home


def config_path() -> Path:
    return _heylead_home() / constants.CONFIG_FILE


def db_path() -> Path:
    return _heylead_home() / constants.DB_DIR / constants.DB_FILE


def cookie_path() -> Path:
    """Legacy — kept for cleanup of old installs."""
    return _heylead_home() / constants.AUTH_DIR / constants.COOKIE_FILE


def log_path() -> Path:
    return _heylead_home() / constants.LOG_DIR / constants.LOG_FILE


# ──────────────────────────────────────────────
# Config read / write
# ──────────────────────────────────────────────

_DEFAULT_CONFIG: dict[str, Any] = {
    "llm_priority": constants.DEFAULT_LLM_PRIORITY,
    "api_keys": {
        "gemini": "",
        "claude": "",
        "openai": "",
    },
    "timezone": "",
    "working_hours": {
        "start": constants.DEFAULT_START_HOUR,
        "end": constants.DEFAULT_END_HOUR,
        "days": constants.DEFAULT_ACTIVE_DAYS,
    },
    "unipile_api_url": "",
    "unipile_api_key": "",
    "tier": constants.TIER_FREE,
    "telemetry": False,
    "gemini_model": constants.DEFAULT_GEMINI_MODEL,
    "claude_model": constants.DEFAULT_CLAUDE_MODEL,
    "openai_model": constants.DEFAULT_OPENAI_MODEL,
}


def load_config() -> dict[str, Any]:
    """Load config from disk, creating default if missing."""
    ensure_dirs()
    path = config_path()
    if path.exists():
        try:
            with open(path, "r") as f:
                data = json.load(f)
            # Merge defaults for any missing keys
            merged = {**_DEFAULT_CONFIG, **data}
            # Deep-merge nested dicts
            for key in ("api_keys", "working_hours"):
                if key in _DEFAULT_CONFIG:
                    merged[key] = {**_DEFAULT_CONFIG[key], **data.get(key, {})}
            return merged
        except (json.JSONDecodeError, IOError) as e:
            logger.warning(f"Config file corrupt, using defaults: {e}")
            return dict(_DEFAULT_CONFIG)
    else:
        save_config(_DEFAULT_CONFIG)
        return dict(_DEFAULT_CONFIG)


def save_config(cfg: dict[str, Any]) -> None:
    """Persist config to disk."""
    ensure_dirs()
    path = config_path()
    with open(path, "w") as f:
        json.dump(cfg, f, indent=2)


def get_api_key(provider: str) -> str:
    """Return API key for a given LLM provider, or empty string."""
    cfg = load_config()
    return cfg.get("api_keys", {}).get(provider, "")


def set_api_key(provider: str, key: str) -> None:
    """Store an API key."""
    cfg = load_config()
    cfg.setdefault("api_keys", {})[provider] = key
    save_config(cfg)


def get_tier() -> str:
    """Return current tier ('free' or 'pro')."""
    cfg = load_config()
    return cfg.get("tier", constants.TIER_FREE)


def get_timezone() -> str:
    """Return configured timezone string, or empty."""
    cfg = load_config()
    return cfg.get("timezone", "")


def set_timezone(tz: str) -> None:
    cfg = load_config()
    cfg["timezone"] = tz
    save_config(cfg)


# ──────────────────────────────────────────────
# Unipile config helpers
# ──────────────────────────────────────────────

def get_unipile_config() -> tuple[str, str]:
    """Return (api_url, api_key) from config."""
    cfg = load_config()
    return cfg.get("unipile_api_url", ""), cfg.get("unipile_api_key", "")


def set_unipile_config(api_url: str, api_key: str) -> None:
    """Store Unipile credentials."""
    cfg = load_config()
    cfg["unipile_api_url"] = api_url.strip()
    cfg["unipile_api_key"] = api_key.strip()
    save_config(cfg)


# ──────────────────────────────────────────────
# Backend proxy config helpers
# ──────────────────────────────────────────────

def get_backend_config() -> tuple[str, str]:
    """Return (backend_url, jwt_token) from config."""
    cfg = load_config()
    return cfg.get("backend_url", ""), cfg.get("backend_jwt", "")


def set_backend_config(backend_url: str, jwt_token: str) -> None:
    """Store backend proxy credentials."""
    cfg = load_config()
    cfg["backend_url"] = backend_url.strip()
    cfg["backend_jwt"] = jwt_token.strip()
    save_config(cfg)


def is_backend_mode() -> bool:
    """Check if the MCP server should use the backend proxy."""
    url, jwt = get_backend_config()
    return bool(url and jwt)
