#!/usr/bin/env python3
"""
PostToolUse hook — Project sync checker
Trigger: Edit/Write on .gd, .tscn, .tres, .md files

Checks:
1. If file belongs to a deliverable → update deliverable status
2. If CHECKPOINT.md is stale → suggest /checkpoint
3. If EventBus modified → check if signals documented
"""

import json
import re
import sys
from pathlib import Path
from datetime import datetime, timedelta
from typing import Optional


def main():
    # Read tool input from stdin
    data = json.load(sys.stdin)
    tool_name = data.get("tool_name", "")
    tool_input = data.get("tool_input", {})

    # Only process Edit and Write tools
    if tool_name not in ("Edit", "Write"):
        return

    file_path = tool_input.get("file_path") or tool_input.get("path", "")

    if not file_path:
        return

    path = Path(file_path)

    # Only process relevant file types
    if path.suffix not in (".gd", ".tscn", ".tres", ".md"):
        return

    project_root = _find_project_root(path)

    if not project_root:
        return

    messages = []

    # Check 1: Deliverable sync
    deliverable = _find_deliverable_for_file(project_root, path)
    if deliverable:
        updated = _update_deliverable_status(deliverable, "in_progress")
        if updated:
            messages.append(f"Livrable '{deliverable.stem}' marqué in_progress")

    # Check 2: Checkpoint staleness
    checkpoint = project_root / "CHECKPOINT.md"
    if checkpoint.exists():
        age = datetime.now() - datetime.fromtimestamp(checkpoint.stat().st_mtime)
        if age > timedelta(hours=2):
            messages.append("CHECKPOINT.md date de plus de 2h — /checkpoint suggéré")

    # Check 3: EventBus sync
    if "event_bus" in path.name.lower():
        messages.append("EventBus modifié — vérifier que GAME_PLAN.md liste les signaux")

    # Check 4: References suggestion for data files
    if path.suffix == ".tres" or "theme" in path.name.lower():
        refs_index = project_root / "references" / "index.md"
        if refs_index.exists():
            messages.append("Fichier data modifié — vérifier cohérence avec references/")

    if messages:
        output = {
            "hookSpecificOutput": {
                "hookEventName": "PostToolUse",
                "additionalContext": "\n".join(messages)
            }
        }
        print(json.dumps(output))


def _find_project_root(path: Path) -> Optional[Path]:
    """Find project root by looking for project.godot"""
    current = path.parent
    for _ in range(10):
        if (current / "project.godot").exists():
            return current
        if current.parent == current:
            break
        current = current.parent
    return None


def _find_deliverable_for_file(project_root: Path, file_path: Path) -> Optional[Path]:
    """Check if file is listed in any deliverable"""
    deliverables_dir = project_root / "deliverables"
    if not deliverables_dir.exists():
        return None

    try:
        rel_path = str(file_path.relative_to(project_root))
    except ValueError:
        rel_path = file_path.name

    for md in deliverables_dir.glob("*.md"):
        try:
            content = md.read_text()
            if rel_path in content or file_path.name in content:
                return md
        except Exception:
            continue

    return None


def _update_deliverable_status(deliverable: Path, new_status: str) -> bool:
    """Update status in deliverable file. Returns True if updated.

    Handles various Status formats:
    - ## Status\\npending
    - ## Status\\n\\npending
    - Status: pending
    - Status:\\npending
    """
    try:
        content = deliverable.read_text()

        # Don't update if already completed (tolerant matching)
        if re.search(r"(?:^|\n)##?\s*Status\s*:?\s*\n*\s*completed", content):
            return False

        # Don't update if already the target status
        if re.search(rf"(?:^|\n)##?\s*Status\s*:?\s*\n*\s*{new_status}", content):
            return False

        # Pattern: "## Status" or "Status" followed by optional colon, newlines, and "pending"
        # Captures the prefix to preserve formatting
        pattern = r"((?:^|\n)##?\s*Status\s*:?\s*\n*\s*)pending"

        if re.search(pattern, content):
            content = re.sub(pattern, rf"\g<1>{new_status}", content)
            deliverable.write_text(content)
            return True

    except Exception:
        pass

    return False


if __name__ == "__main__":
    main()
