from .base import BaseRepo


class TaskRepo(BaseRepo):

    def batch_create(self, feature_id: str, tasks: list[dict], task_type: str = "manual") -> dict:
        created, skipped = 0, 0
        now = self._now()
        # 一次查询加载所有已有记录到内存
        existing_rows = self.conn.execute(
            "SELECT id, title, parent_id, sort_order FROM tasks WHERE project_dir=? AND feature_id=?",
            (self.project_dir, feature_id)
        ).fetchall()
        existing_map = {(r["title"], r["parent_id"]): r for r in existing_rows}

        for task in tasks:
            title = task["title"]
            parent_id = task.get("parent_id", 0)
            sort_order = task.get("sort_order", 0)
            metadata = task.get("metadata", "{}")
            
            if (title, parent_id) in existing_map:
                skipped += 1
                continue
            
            self.conn.execute(
                "INSERT INTO tasks (project_dir, feature_id, title, status, parent_id, task_type, sort_order, metadata, created_at, updated_at) "
                "VALUES (?,?,?,?,?,?,?,?,?,?)",
                (self.project_dir, feature_id, title, "pending", parent_id, task_type, sort_order, metadata, now, now)
            )
            created += 1
        
        self._commit()
        return {"created": created, "skipped": skipped}

    def update(self, task_id: int, **fields) -> dict:
        if not fields:
            return self.get(task_id)
        fields["updated_at"] = self._now()
        set_clause = ", ".join(f"{k}=?" for k in fields)
        self.conn.execute(
            f"UPDATE tasks SET {set_clause} WHERE id=?",
            [*fields.values(), task_id]
        )
        self._commit()
        return self.get(task_id)

    def get(self, task_id: int) -> dict:
        row = self.conn.execute("SELECT * FROM tasks WHERE id=?", (task_id,)).fetchone()
        return dict(row) if row else {}

    def list_by_feature(self, feature_id: str) -> list[dict]:
        return [dict(r) for r in self.conn.execute(
            "SELECT * FROM tasks WHERE project_dir=? AND feature_id=? ORDER BY sort_order, id",
            (self.project_dir, feature_id)
        ).fetchall()]

    def delete(self, task_id: int) -> bool:
        cursor = self.conn.execute("DELETE FROM tasks WHERE id=?", (task_id,))
        self._commit()
        return cursor.rowcount > 0

    def archive_by_feature(self, feature_id: str) -> dict:
        tasks = self.list_by_feature(feature_id)
        if not tasks:
            return {"archived": 0}
        
        now = self._now()
        for task in tasks:
            self.conn.execute(
                "INSERT INTO tasks_archive (id, project_dir, feature_id, title, status, parent_id, task_type, sort_order, metadata, created_at, updated_at, archived_at) "
                "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)",
                (task["id"], task["project_dir"], task["feature_id"], task["title"], task["status"],
                 task["parent_id"], task["task_type"], task["sort_order"], task["metadata"],
                 task["created_at"], task["updated_at"], now)
            )
        
        self.conn.execute(
            "DELETE FROM tasks WHERE project_dir=? AND feature_id=?",
            (self.project_dir, feature_id)
        )
        self._commit()
        return {"archived": len(tasks)}

    def list_archived(self, feature_id: str | None = None) -> list[dict]:
        if feature_id:
            return [dict(r) for r in self.conn.execute(
                "SELECT * FROM tasks_archive WHERE project_dir=? AND feature_id=? ORDER BY sort_order, id",
                (self.project_dir, feature_id)
            ).fetchall()]
        return [dict(r) for r in self.conn.execute(
            "SELECT * FROM tasks_archive WHERE project_dir=? ORDER BY archived_at DESC",
            (self.project_dir,)
        ).fetchall()]

    def get_feature_status(self, feature_id: str) -> str:
        rows = self.conn.execute(
            "SELECT status FROM tasks WHERE project_dir=? AND feature_id=?",
            (self.project_dir, feature_id)
        ).fetchall()
        if not rows:
            return "pending"
        statuses = {r["status"] for r in rows}
        if statuses == {"completed"}:
            return "completed"
        if statuses == {"pending"}:
            return "pending"
        return "in_progress"
