"""Configuration management for Nogic CLI."""

import os
import json
from pathlib import Path
from dataclasses import dataclass, field
from typing import Optional

from dotenv import load_dotenv

load_dotenv()

CONFIG_DIR = ".nogic"
CONFIG_FILE = "config.json"
GLOBAL_CONFIG_DIR = Path.home() / ".nogic"

_PRODUCTION_URL = "https://api.nogic.dev"


def is_dev_mode() -> bool:
    """True when NOGIC_API_URL env var overrides the production URL."""
    return bool(os.getenv("NOGIC_API_URL"))


def get_api_url() -> str:
    """Return NOGIC_API_URL if set, otherwise the production URL."""
    return os.getenv("NOGIC_API_URL", _PRODUCTION_URL).strip().rstrip("/")


def dev_mode_banner() -> str | None:
    """Return a dev mode banner string, or None if in production mode."""
    if is_dev_mode():
        return f"[DEV] Using {get_api_url()}"
    return None


@dataclass
class Config:
    api_key: Optional[str]
    project_id: Optional[str]
    project_name: Optional[str] = None
    directory_hash: Optional[str] = None

    @property
    def api_url(self) -> str:
        return get_api_url()

    @classmethod
    def load(cls, directory: Path = Path.cwd()) -> "Config":
        """
        Load config from multiple sources (priority order):
        1. Environment variables
        2. Global config: ~/.nogic/config.json (api_key)
        3. Local config: <directory>/.nogic/config.json (project_id, project_name, directory_hash)
        """
        api_key = os.getenv("NOGIC_API_KEY")
        project_id = None
        project_name = None
        directory_hash = None

        global_config_path = GLOBAL_CONFIG_DIR / CONFIG_FILE
        if global_config_path.exists():
            try:
                with open(global_config_path, encoding="utf-8") as f:
                    data = json.load(f)
                    if not api_key:
                        api_key = data.get("api_key")
            except (json.JSONDecodeError, OSError):
                pass  # Corrupted config - continue with defaults

        local_config_path = directory / CONFIG_DIR / CONFIG_FILE
        if local_config_path.exists():
            try:
                with open(local_config_path, encoding="utf-8") as f:
                    data = json.load(f)
                    project_id = data.get("project_id")
                    project_name = data.get("project_name")
                    directory_hash = data.get("directory_hash")
            except (json.JSONDecodeError, OSError):
                pass  # Corrupted config - continue with defaults

        if api_key:
            api_key = api_key.strip()

        return cls(
            api_key=api_key,
            project_id=project_id,
            project_name=project_name,
            directory_hash=directory_hash,
        )

    def save_global(self):
        """Save API key to ~/.nogic/config.json (preserves other settings)."""
        GLOBAL_CONFIG_DIR.mkdir(mode=0o700, exist_ok=True)

        existing = {}
        config_path = GLOBAL_CONFIG_DIR / CONFIG_FILE
        if config_path.exists():
            try:
                with open(config_path, encoding="utf-8") as f:
                    existing = json.load(f)
            except (json.JSONDecodeError, OSError):
                pass  # Corrupted config - will be overwritten

        if self.api_key:
            existing["api_key"] = self.api_key

        # Never store api_url on disk
        existing.pop("api_url", None)

        with open(config_path, "w", encoding="utf-8") as f:
            json.dump(existing, f, indent=2)

        os.chmod(config_path, 0o600)

    def save_local(self, directory: Path = Path.cwd()):
        """Save project config to <directory>/.nogic/config.json."""
        config_dir = directory / CONFIG_DIR
        config_dir.mkdir(mode=0o700, exist_ok=True)

        data = {}
        if self.project_id:
            data["project_id"] = self.project_id
        if self.project_name:
            data["project_name"] = self.project_name
        if self.directory_hash:
            data["directory_hash"] = self.directory_hash

        config_path = config_dir / CONFIG_FILE
        with open(config_path, "w", encoding="utf-8") as f:
            json.dump(data, f, indent=2)

        os.chmod(config_path, 0o600)

    def save(self, directory: Path = Path.cwd()):
        """Save both global and local config."""
        self.save_global()
        self.save_local(directory)


def get_cli_db_path(project_id: str) -> Path:
    """Get the CLI's sync database path: ~/.nogic/sync/<project_id>/data.db"""
    sync_dir = GLOBAL_CONFIG_DIR / "sync" / project_id
    sync_dir.mkdir(mode=0o700, parents=True, exist_ok=True)
    return sync_dir / "data.db"


def get_language(path: Path) -> Optional[str]:
    """Get language from file extension."""
    ext_map = {
        ".py": "python",
        ".js": "javascript",
        ".jsx": "javascript",
        ".ts": "typescript",
        ".tsx": "typescript",
    }
    return ext_map.get(path.suffix.lower())
