import json
from pathlib import Path
from datetime import datetime
from typing import Optional, List
import structlog

logger = structlog.get_logger()


class ProjectMemory:
    """
    项目记忆管理器
    持久化存储任务历史、架构决策、常见问题等
    """

    def __init__(self, memory_dir: str = "./memory"):
        self.memory_dir = Path(memory_dir)
        self.memory_dir.mkdir(parents=True, exist_ok=True)
        self.logger = structlog.get_logger().bind(component="project_memory")

    def save_task(self, task_id: str, state: dict) -> bool:
        """保存任务完整状态到记忆"""
        record = {
            "task_id": task_id,
            "saved_at": datetime.utcnow().isoformat(),
            "user_request": state.get("user_request", ""),
            "repo_path": state.get("repo_path", ""),
            "status": state.get("status", ""),
            "architecture_plan": state.get("architecture_plan", {}),
            "test_result": state.get("test_result", {}),
            "review_result": state.get("review_result", {}),
            "diff_summary": {
                "modified": state.get("diff_result", {}).get("modified", []),
                "added": state.get("diff_result", {}).get("added", []),
            },
        }
        path = self.memory_dir / f"{task_id}.json"
        path.write_text(json.dumps(record, indent=2, ensure_ascii=False), encoding="utf-8")
        self.logger.info("Task saved to memory", task_id=task_id)
        return True

    def load_task(self, task_id: str) -> Optional[dict]:
        """加载任务记忆"""
        path = self.memory_dir / f"{task_id}.json"
        if not path.exists():
            return None
        return json.loads(path.read_text(encoding="utf-8"))

    def get_similar_tasks(self, user_request: str, limit: int = 3) -> List[dict]:
        """查找相似历史任务（简单关键词匹配）"""
        keywords = set(user_request.lower().split())
        results = []

        for f in self.memory_dir.glob("*.json"):
            try:
                record = json.loads(f.read_text(encoding="utf-8"))
                req_words = set(record.get("user_request", "").lower().split())
                overlap = len(keywords & req_words)
                if overlap > 0:
                    results.append((overlap, record))
            except Exception:
                pass

        results.sort(key=lambda x: x[0], reverse=True)
        return [r for _, r in results[:limit]]

    def list_tasks(self, limit: int = 20) -> List[dict]:
        """列出最近任务"""
        records = []
        for f in sorted(self.memory_dir.glob("*.json"), key=lambda x: x.stat().st_mtime, reverse=True)[:limit]:
            try:
                records.append(json.loads(f.read_text(encoding="utf-8")))
            except Exception:
                pass
        return records

    def delete_task(self, task_id: str) -> bool:
        path = self.memory_dir / f"{task_id}.json"
        if path.exists():
            path.unlink()
            return True
        return False

    def get_context_for_task(self, user_request: str) -> dict:
        """为新任务构建历史上下文"""
        similar = self.get_similar_tasks(user_request)
        if not similar:
            return {}
        return {
            "similar_tasks": [
                {
                    "request": t.get("user_request", ""),
                    "architecture": t.get("architecture_plan", {}),
                    "status": t.get("status", ""),
                }
                for t in similar
            ]
        }
