"""
笔记本操作模块
提供笔记本的增删改查功能
"""

from typing import Any, Dict, List, Optional
from .base import client


def _get_default_kernel() -> str:
    """获取服务器默认内核"""
    try:
        kernelspecs = client.request('/api/kernelspecs')
        return kernelspecs.get('default', 'python3')
    except:
        return 'python3'


class NotebookManager:
    """笔记本管理器"""
    
    @staticmethod
    def list_all() -> List[Dict[str, Any]]:
        """
        列出所有笔记本
        
        Returns:
            笔记本列表
        """
        contents = client.request('/api/contents')
        notebooks = []
        
        def extract_notebooks(items):
            for item in items:
                if item.get('type') == 'notebook':
                    notebooks.append({
                        'name': item.get('name'),
                        'path': item.get('path'),
                        'created': item.get('created'),
                        'last_modified': item.get('last_modified'),
                        'size': item.get('size', 0)
                    })
                elif item.get('type') == 'directory':
                    # 递归查询子目录
                    sub_path = item.get('path', '')
                    try:
                        sub_contents = client.request(f'/api/contents/{sub_path}')
                        extract_notebooks(sub_contents.get('content', []))
                    except:
                        continue
        
        extract_notebooks(contents.get('content', []))
        return notebooks
    
    @staticmethod
    def create(path: str, kernel_name: Optional[str] = None) -> Dict[str, Any]:
        """
        创建新笔记本
        
        Args:
            path: 笔记本路径
            kernel_name: 内核名称（可选，不提供则使用服务器默认内核）
            
        Returns:
            创建的笔记本信息
        """
        # 如果没有指定内核，获取服务器的默认内核
        if not kernel_name:
            kernel_name = _get_default_kernel()
        
        notebook_data = {
            "type": "notebook",
            "content": {
                "cells": [],
                "metadata": {
                    "kernelspec": {
                        "display_name": "Python 3",
                        "language": "python",
                        "name": kernel_name
                    },
                    "language_info": {
                        "name": "python",
                        "version": "3.8.0"
                    }
                },
                "nbformat": 4,
                "nbformat_minor": 4
            }
        }
        
        return client.request(f'/api/contents/{path}', 'PUT', notebook_data)
    
    @staticmethod
    def get(path: str) -> Dict[str, Any]:
        """
        获取笔记本内容
        
        Args:
            path: 笔记本路径
            
        Returns:
            笔记本完整内容
        """
        return client.request(f'/api/contents/{path}')
    
    @staticmethod
    def update(path: str, content: Dict[str, Any]) -> Dict[str, Any]:
        """
        更新笔记本内容
        
        Args:
            path: 笔记本路径
            content: 笔记本内容（完整的notebook JSON结构）
            
        Returns:
            更新后的笔记本信息
        """
        notebook_data = {
            "type": "notebook",
            "content": content
        }
        return client.request(f'/api/contents/{path}', 'PUT', notebook_data)
    
    @staticmethod
    def delete(path: str) -> Dict[str, Any]:
        """
        删除笔记本
        
        Args:
            path: 笔记本路径
            
        Returns:
            删除结果
        """
        client.request(f'/api/contents/{path}', 'DELETE')
        return {"path": path, "status": "deleted"}
    
    @staticmethod
    def add_cell(path: str, source: str, cell_type: str = "code", 
                position: Optional[int] = None) -> Dict[str, Any]:
        """
        添加单元格
        
        Args:
            path: 笔记本路径
            source: 单元格内容
            cell_type: 单元格类型 ("code" 或 "markdown")
            position: 插入位置（None表示追加到末尾）
            
        Returns:
            更新后的笔记本信息
        """
        notebook = NotebookManager.get(path)
        notebook_content = notebook.get('content', {})
        cells = notebook_content.get('cells', [])
        
        # 创建新单元格
        new_cell = {
            "cell_type": cell_type,
            "metadata": {},
            "source": source if isinstance(source, list) else [source]
        }
        
        if cell_type == "code":
            new_cell["execution_count"] = None
            new_cell["outputs"] = []
        
        # 插入单元格
        if position is None:
            cells.append(new_cell)
        else:
            cells.insert(position, new_cell)
        
        notebook_content['cells'] = cells
        return NotebookManager.update(path, notebook_content)
    
    @staticmethod
    def update_cell(path: str, cell_index: int, source: str) -> Dict[str, Any]:
        """
        更新单元格内容
        
        Args:
            path: 笔记本路径
            cell_index: 单元格索引（从0开始）
            source: 新的单元格内容
            
        Returns:
            更新后的笔记本信息
        """
        notebook = NotebookManager.get(path)
        notebook_content = notebook.get('content', {})
        cells = notebook_content.get('cells', [])
        
        if cell_index < 0 or cell_index >= len(cells):
            raise Exception(f"单元格索引 {cell_index} 超出范围（共 {len(cells)} 个单元格）")
        
        # 更新单元格内容
        cells[cell_index]['source'] = source if isinstance(source, list) else [source]
        
        # 如果是代码单元格，清空输出
        if cells[cell_index].get('cell_type') == 'code':
            cells[cell_index]['outputs'] = []
            cells[cell_index]['execution_count'] = None
        
        notebook_content['cells'] = cells
        return NotebookManager.update(path, notebook_content)
    
    @staticmethod
    def delete_cell(path: str, cell_index: int) -> Dict[str, Any]:
        """
        删除单元格
        
        Args:
            path: 笔记本路径
            cell_index: 要删除的单元格索引（从0开始）
            
        Returns:
            更新后的笔记本信息
        """
        notebook = NotebookManager.get(path)
        notebook_content = notebook.get('content', {})
        cells = notebook_content.get('cells', [])
        
        if cell_index < 0 or cell_index >= len(cells):
            raise Exception(f"单元格索引 {cell_index} 超出范围（共 {len(cells)} 个单元格）")
        
        # 删除单元格
        cells.pop(cell_index)
        notebook_content['cells'] = cells
        return NotebookManager.update(path, notebook_content)


# 导出单例
notebook_manager = NotebookManager()
