"""Scan ~/.claude/projects/ for session data."""

from __future__ import annotations

import json
import logging
from pathlib import Path

from cc_logger.types.session import ProjectInfo, SessionInfo

logger = logging.getLogger(__name__)


def scan_projects(claude_dir: Path) -> list[ProjectInfo]:
    """Scan claude_dir/projects/ for all projects and their sessions."""
    projects_dir = claude_dir / "projects"
    if not projects_dir.is_dir():
        logger.warning("No projects directory found at %s", projects_dir)
        return []

    projects: list[ProjectInfo] = []
    for entry in sorted(projects_dir.iterdir()):
        if not entry.is_dir():
            continue
        project = _load_project(entry)
        if project.sessions:
            projects.append(project)
    return projects


def _load_project(project_dir: Path) -> ProjectInfo:
    """Load a single project directory, reading sessions-index.json or falling back to JSONL scan."""
    slug = project_dir.name
    index_path = project_dir / "sessions-index.json"

    if index_path.is_file():
        try:
            index_data = json.loads(index_path.read_text())
            original_path = index_data.get("originalPath", slug)
            sessions = _sessions_from_index(index_data, project_dir, slug, original_path)
            return ProjectInfo(
                slug=slug,
                original_path=original_path,
                directory=project_dir,
                sessions=sessions,
            )
        except (json.JSONDecodeError, KeyError) as e:
            logger.warning("Corrupted sessions-index.json in %s: %s, falling back to JSONL scan", slug, e)

    # Fallback: scan for JSONL files directly
    sessions = _sessions_from_jsonl_scan(project_dir, slug)
    original_path = slug.replace("-", "/") if slug.startswith("-") else slug
    return ProjectInfo(
        slug=slug,
        original_path=original_path,
        directory=project_dir,
        sessions=sessions,
    )


def _sessions_from_index(
    index_data: dict, project_dir: Path, slug: str, original_path: str
) -> list[SessionInfo]:
    """Parse sessions from a sessions-index.json."""
    sessions: list[SessionInfo] = []
    for entry in index_data.get("entries", []):
        session_id = entry.get("sessionId", "")
        if not session_id:
            continue
        jsonl_path = project_dir / f"{session_id}.jsonl"
        if not jsonl_path.is_file():
            full_path = entry.get("fullPath")
            if full_path:
                jsonl_path = Path(full_path)
            if not jsonl_path.is_file():
                continue
        sessions.append(
            SessionInfo(
                session_id=session_id,
                jsonl_path=jsonl_path,
                project_path=original_path,
                project_slug=slug,
                created=entry.get("created"),
                modified=entry.get("modified"),
                first_prompt=entry.get("firstPrompt"),
                message_count=entry.get("messageCount", 0),
                git_branch=entry.get("gitBranch"),
            )
        )
    return sessions


def _sessions_from_jsonl_scan(project_dir: Path, slug: str) -> list[SessionInfo]:
    """Fallback: discover sessions by scanning for *.jsonl files."""
    sessions: list[SessionInfo] = []
    for jsonl_path in sorted(project_dir.glob("*.jsonl")):
        session_id = jsonl_path.stem
        # Try to read first line for metadata
        first_prompt = None
        version = None
        try:
            with open(jsonl_path) as f:
                first_line = f.readline().strip()
                if first_line:
                    data = json.loads(first_line)
                    msg = data.get("message", {})
                    if isinstance(msg, dict):
                        content = msg.get("content")
                        if isinstance(content, str):
                            first_prompt = content[:200]
                    version = data.get("version")
        except (json.JSONDecodeError, OSError):
            pass

        original_path = slug.replace("-", "/") if slug.startswith("-") else slug
        sessions.append(
            SessionInfo(
                session_id=session_id,
                jsonl_path=jsonl_path,
                project_path=original_path,
                project_slug=slug,
                first_prompt=first_prompt,
            )
        )
    return sessions
