"""Aider collector: parses Aider markdown chat history files."""

import re
from pathlib import Path
from typing import Optional

from memotrail.utils import get_logger

logger = get_logger("memotrail.collectors.aider")

# Aider stores chat history in .aider.chat.history.md files
# Format: alternating USER/ASSISTANT blocks separated by headers

_ROLE_PATTERN = re.compile(r"^####\s+(USER|ASSISTANT)\s*$", re.MULTILINE)
_DIVIDER_PATTERN = re.compile(r"^---+\s*$", re.MULTILINE)


def find_session_files(search_dir: Path | None = None) -> list[Path]:
    """Find all Aider chat history files.

    Aider stores history in `.aider.chat.history.md` in the project root.
    Searches common locations if no directory specified.
    """
    if search_dir:
        dirs_to_search = [search_dir]
    else:
        # Search in home directory and common project locations
        home = Path.home()
        dirs_to_search = [
            home,
            home / "projects",
            home / "code",
            home / "dev",
            home / "Documents",
            home / "workspace",
        ]

    history_files = []

    for base_dir in dirs_to_search:
        if not base_dir.exists():
            continue
        # Search up to 3 levels deep
        for pattern in [
            ".aider.chat.history.md",
            "*/.aider.chat.history.md",
            "*/*/.aider.chat.history.md",
        ]:
            for f in base_dir.glob(pattern):
                if f.is_file() and f.stat().st_size > 0:
                    history_files.append(f)

    # Deduplicate
    seen = set()
    unique = []
    for f in history_files:
        resolved = f.resolve()
        if resolved not in seen:
            seen.add(resolved)
            unique.append(f)

    logger.info(f"Found {len(unique)} Aider history file(s)")
    return sorted(unique)


def parse_session_file(filepath: Path) -> list[dict]:
    """Parse an Aider .aider.chat.history.md file.

    Aider's format uses `#### USER` and `#### ASSISTANT` headers
    to delimit messages, with `---` separating sessions.

    Returns:
        List of session dicts, each with: project, messages, source_file
    """
    try:
        content = filepath.read_text(encoding="utf-8")
    except Exception as e:
        logger.error(f"Error reading {filepath}: {e}")
        return []

    project = _infer_project(filepath)

    # Split into sessions by divider
    raw_sessions = _DIVIDER_PATTERN.split(content)
    sessions = []

    for raw in raw_sessions:
        raw = raw.strip()
        if not raw:
            continue

        messages = _parse_messages(raw)
        if messages:
            sessions.append({
                "project": project,
                "messages": messages,
                "source_file": str(filepath),
            })

    logger.info(f"Parsed {len(sessions)} session(s) from {filepath}")
    return sessions


def _parse_messages(raw_session: str) -> list[dict]:
    """Parse messages from a single Aider session block."""
    messages = []

    # Find all role headers and their positions
    matches = list(_ROLE_PATTERN.finditer(raw_session))
    if not matches:
        return []

    for i, match in enumerate(matches):
        role_text = match.group(1).lower()
        role = "user" if role_text == "user" else "assistant"

        # Content starts after the header line
        content_start = match.end()
        # Content ends at the next header or end of string
        content_end = matches[i + 1].start() if i + 1 < len(matches) else len(raw_session)

        content = raw_session[content_start:content_end].strip()

        if content:
            messages.append({
                "role": role,
                "content": content,
                "timestamp": "",  # Aider doesn't include timestamps
            })

    return messages


def _infer_project(filepath: Path) -> Optional[str]:
    """Infer project name from file location.

    The .aider.chat.history.md file is usually in the project root,
    so the parent directory name is the project name.
    """
    return filepath.parent.name


def collect_all_sessions(search_dir: Path | None = None) -> list[dict]:
    """Collect and parse all Aider sessions."""
    files = find_session_files(search_dir)
    all_sessions = []

    for f in files:
        sessions = parse_session_file(f)
        for s in sessions:
            if s["messages"]:
                all_sessions.append(s)
                logger.info(
                    f"Collected Aider session: {s['project'] or 'unknown'} "
                    f"({len(s['messages'])} messages)"
                )

    logger.info(f"Collected {len(all_sessions)} Aider sessions total")
    return all_sessions
