"""Parser for Cursor AI conversation data.

Cursor stores data in SQLite databases:
~/Library/.../Cursor/User/workspaceStorage/<hash>/state.vscdb

Each workspace has:
- workspace.json: maps hash to project folder (file:///path/to/project)
- state.vscdb: SQLite with ItemTable containing:
  - composer.composerData: JSON with allComposers array (agent/edit sessions)
  - workbench.panel.aichat.chatdata: JSON array of chat messages
"""
import json
import sqlite3
from pathlib import Path
from urllib.parse import unquote, urlparse


def _find_workspace_db(project_path: str, cursor_dir: Path) -> Path | None:
    """Find the state.vscdb for a given project path."""
    ws_storage = cursor_dir / "workspaceStorage"
    if not ws_storage.exists():
        return None

    for ws_dir in ws_storage.iterdir():
        if not ws_dir.is_dir():
            continue
        ws_json = ws_dir / "workspace.json"
        if not ws_json.exists():
            continue
        try:
            with open(ws_json) as f:
                data = json.load(f)
            folder = data.get("folder", "")
            # Convert file:///Users/test/my-app -> /Users/test/my-app
            if folder.startswith("file://"):
                parsed = urlparse(folder)
                folder = unquote(parsed.path)
            if folder == project_path:
                db_path = ws_dir / "state.vscdb"
                if db_path.exists():
                    return db_path
        except (json.JSONDecodeError, KeyError):
            continue

    return None


def _count_composer_sessions(conn: sqlite3.Connection) -> int:
    """Count composer sessions (agent/edit interactions)."""
    try:
        cursor = conn.execute(
            "SELECT value FROM ItemTable WHERE key = 'composer.composerData'"
        )
        row = cursor.fetchone()
        if not row:
            return 0
        data = json.loads(row[0])
        composers = data.get("allComposers", [])
        return len(composers)
    except (sqlite3.Error, json.JSONDecodeError):
        return 0


def _count_chat_prompts(conn: sqlite3.Connection) -> int:
    """Count user messages from chat data."""
    try:
        # Try multiple possible keys for chat data
        for key in ["workbench.panel.aichat.chatdata"]:
            cursor = conn.execute(
                "SELECT value FROM ItemTable WHERE key = ?", (key,)
            )
            row = cursor.fetchone()
            if row:
                data = json.loads(row[0])
                if isinstance(data, list):
                    return sum(1 for msg in data if isinstance(msg, dict) and msg.get("role") == "user")
        return 0
    except (sqlite3.Error, json.JSONDecodeError):
        return 0


def count_for_project(project_path: str, cursor_dir: Path) -> dict:
    """Count prompts for a project from Cursor workspace storage.

    Returns: {"prompts": N, "composer_sessions": M, "chat_prompts": P}
    """
    db_path = _find_workspace_db(project_path, cursor_dir)
    if not db_path:
        return {"prompts": 0, "composer_sessions": 0, "chat_prompts": 0}

    try:
        conn = sqlite3.connect(str(db_path))
        composer = _count_composer_sessions(conn)
        chat = _count_chat_prompts(conn)
        conn.close()
        return {
            "prompts": composer + chat,
            "composer_sessions": composer,
            "chat_prompts": chat,
        }
    except sqlite3.Error:
        return {"prompts": 0, "composer_sessions": 0, "chat_prompts": 0}


def _get_composer_list(conn: sqlite3.Connection) -> list[dict]:
    """Get individual composer sessions with metadata."""
    try:
        cursor = conn.execute(
            "SELECT value FROM ItemTable WHERE key = 'composer.composerData'"
        )
        row = cursor.fetchone()
        if not row:
            return []
        data = json.loads(row[0])
        return data.get("allComposers", [])
    except (sqlite3.Error, json.JSONDecodeError):
        return []


def list_chats(project_path: str, cursor_dir: Path) -> list[dict]:
    """List all chat sessions for a project, sorted by most recent first.

    Returns list of: {"name": str, "mode": str, "created": str,
                      "modified": str, "tool": "cursor"}
    """
    db_path = _find_workspace_db(project_path, cursor_dir)
    if not db_path:
        return []

    try:
        conn = sqlite3.connect(str(db_path))
        composers = _get_composer_list(conn)
        conn.close()
    except sqlite3.Error:
        return []

    chats = []
    for comp in composers:
        created = comp.get("createdAt", 0)
        modified = comp.get("lastUpdatedAt", created)
        chats.append({
            "name": comp.get("name", "Untitled"),
            "mode": comp.get("unifiedMode", ""),
            "created": created,
            "modified": modified,
            "tool": "cursor",
        })

    # Sort by modified timestamp descending
    chats.sort(key=lambda c: c.get("modified", 0), reverse=True)
    return chats
