"""Load SOUL.md and playbook files — file I/O separated from prompt composition."""

from pathlib import Path

import structlog

from fliiq.runtime.package_data import bundled_playbooks_dir, bundled_soul_path

log = structlog.get_logger()

# Default locations relative to project root
_DEFAULT_SOUL = "SOUL.md"
_USER_SOUL = ".fliiq/SOUL.md"
_PLAYBOOKS_DIR = "playbooks"
_USER_PLAYBOOKS_DIR = ".fliiq/playbooks"


def _find_project_root(start: Path | None = None) -> Path:
    """Walk up from start (or cwd) looking for project root markers (.fliiq/ or SOUL.md)."""
    if start:
        current = start
        for parent in [current, *current.parents]:
            if (parent / ".fliiq").is_dir() or (parent / _DEFAULT_SOUL).exists():
                return parent
        return current
    # No explicit start — delegate to config module for global fallback
    from fliiq.runtime.config import resolve_fliiq_dir

    try:
        return resolve_fliiq_dir().parent
    except FileNotFoundError:
        return Path.cwd()


def load_soul(project_root: Path | None = None) -> tuple[str, str | None]:
    """Load default SOUL.md and optional user override.

    Returns (default_soul_content, user_soul_content_or_None).
    """
    root = project_root or _find_project_root()

    default_path = root / _DEFAULT_SOUL
    if not default_path.exists():
        # Fall back to bundled SOUL.md
        bundled = bundled_soul_path()
        if bundled.exists():
            default_path = bundled
        else:
            raise FileNotFoundError(f"SOUL.md not found at {root / _DEFAULT_SOUL} or bundled location")

    default_soul = default_path.read_text()

    user_path = root / _USER_SOUL
    user_soul = user_path.read_text() if user_path.exists() else None

    return default_soul, user_soul


def load_playbook(domain: str, project_root: Path | None = None) -> str | None:
    """Load a playbook by domain name. User overrides take priority.

    Resolution order: .fliiq/playbooks/{domain}.md → playbooks/{domain}.md
    """
    root = project_root or _find_project_root()

    # User override first
    user_pb = root / _USER_PLAYBOOKS_DIR / f"{domain}.md"
    if user_pb.exists():
        log.debug("loading_user_playbook", domain=domain, path=str(user_pb))
        return user_pb.read_text()

    # Default playbook
    default_pb = root / _PLAYBOOKS_DIR / f"{domain}.md"
    if default_pb.exists():
        log.debug("loading_default_playbook", domain=domain, path=str(default_pb))
        return default_pb.read_text()

    # Bundled fallback
    bundled_pb = bundled_playbooks_dir() / f"{domain}.md"
    if bundled_pb.exists():
        log.debug("loading_bundled_playbook", domain=domain, path=str(bundled_pb))
        return bundled_pb.read_text()

    return None
