"""
文件操作模块
提供文件的增删改查、上传下载功能
"""

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


class FileManager:
    """文件管理器"""
    
    @staticmethod
    def list_directory(dir_path: str = "") -> List[Dict[str, Any]]:
        """
        列出目录内容
        
        Args:
            dir_path: 目录路径（空字符串表示根目录）
            
        Returns:
            目录内容列表
        """
        if dir_path:
            endpoint = f'/api/contents/{dir_path}'
        else:
            endpoint = '/api/contents'
        
        content = client.request(endpoint)
        
        if content.get('type') != 'directory':
            raise Exception(f"路径不是目录: {dir_path}")
        
        items = []
        for item in content.get('content', []):
            item_info = {
                "name": item.get('name'),
                "path": item.get('path'),
                "type": item.get('type'),
                "size": item.get('size', 0),
                "created": item.get('created'),
                "last_modified": item.get('last_modified')
            }
            items.append(item_info)
        
        return items
    
    @staticmethod
    def get_info(file_path: str) -> Dict[str, Any]:
        """
        获取文件信息
        
        Args:
            file_path: 文件路径
            
        Returns:
            文件信息
        """
        content = client.request(f'/api/contents/{file_path}')
        
        file_info = {
            "name": content.get('name'),
            "path": content.get('path'),
            "type": content.get('type'),
            "created": content.get('created'),
            "last_modified": content.get('last_modified'),
            "size": content.get('size', 0),
            "writable": content.get('writable', False)
        }
        
        if content.get('type') == 'file':
            file_info.update({
                "format": content.get('format', 'text'),
                "mimetype": content.get('mimetype', '')
            })
        elif content.get('type') == 'notebook':
            cells = content.get('content', {}).get('cells', [])
            file_info.update({
                "format": "json",
                "cells_count": len(cells),
                "kernelspec": content.get('content', {}).get('metadata', {}).get('kernelspec', {})
            })
        
        return file_info
    
    @staticmethod
    def read(file_path: str) -> Dict[str, Any]:
        """
        读取文件内容
        
        Args:
            file_path: 文件路径
            
        Returns:
            文件内容
        """
        return client.request(f'/api/contents/{file_path}')
    
    @staticmethod
    def write(file_path: str, content: str, file_type: str = "file", 
             format_type: str = "text") -> Dict[str, Any]:
        """
        写入文件内容
        
        Args:
            file_path: 文件路径
            content: 文件内容
            file_type: 文件类型 ("file" 或 "notebook")
            format_type: 格式类型 ("text", "base64", "json")
            
        Returns:
            写入结果
        """
        file_data = {
            "type": file_type,
            "format": format_type,
            "content": content
        }
        
        return client.request(f'/api/contents/{file_path}', 'PUT', file_data)
    
    @staticmethod
    def delete(file_path: str) -> Dict[str, Any]:
        """
        删除文件
        
        Args:
            file_path: 文件路径
            
        Returns:
            删除结果
        """
        client.request(f'/api/contents/{file_path}', 'DELETE')
        return {"path": file_path, "status": "deleted"}
    
    @staticmethod
    def download(file_path: str, local_path: Optional[str] = None) -> Dict[str, Any]:
        """
        下载文件到本地
        
        Args:
            file_path: 远程文件路径
            local_path: 本地保存路径（可选）
            
        Returns:
            下载结果信息
        """
        content = client.request(f'/api/contents/{file_path}')
        
        file_type = content.get('type', 'file')
        file_name = content.get('name', file_path.split('/')[-1])
        
        if file_type == 'file':
            # 普通文件
            file_content = content.get('content', '')
            format_type = content.get('format', 'text')
            
            if format_type == 'base64':
                # 二进制文件（base64 编码）
                file_data = base64.b64decode(file_content)
            else:
                # 文本文件
                file_data = file_content.encode('utf-8')
            
            # 确定本地保存路径
            if not local_path:
                local_path = file_name
            
            # 保存文件到本地
            with open(local_path, 'wb') as f:
                f.write(file_data)
            
            return {
                "file_path": file_path,
                "local_path": local_path,
                "file_type": file_type,
                "format": format_type,
                "size": len(file_data),
                "downloaded": True
            }
            
        elif file_type == 'notebook':
            # Jupyter 笔记本文件
            notebook_content = content.get('content', {})
            
            # 确定本地保存路径
            if not local_path:
                local_path = file_name
            
            # 保存笔记本为 JSON 文件
            with open(local_path, 'w', encoding='utf-8') as f:
                json.dump(notebook_content, f, ensure_ascii=False, indent=2)
            
            return {
                "file_path": file_path,
                "local_path": local_path,
                "file_type": file_type,
                "format": "json",
                "cells": len(notebook_content.get('cells', [])),
                "downloaded": True
            }
            
        elif file_type == 'directory':
            # 目录 - 不支持下载
            raise Exception(f"无法下载目录: {file_path}")
            
        else:
            raise Exception(f"不支持的文件类型: {file_type}")
    
    @staticmethod
    def upload(local_path: str, remote_path: str) -> Dict[str, Any]:
        """
        上传本地文件到远程
        
        Args:
            local_path: 本地文件路径
            remote_path: 远程保存路径
            
        Returns:
            上传结果
        """
        # 读取本地文件
        try:
            with open(local_path, 'rb') as f:
                file_data = f.read()
        except Exception as e:
            raise Exception(f"读取本地文件失败: {str(e)}")
        
        # 判断是否为文本文件
        try:
            content = file_data.decode('utf-8')
            format_type = "text"
        except UnicodeDecodeError:
            # 二进制文件，使用base64编码
            content = base64.b64encode(file_data).decode('utf-8')
            format_type = "base64"
        
        # 上传文件
        return FileManager.write(remote_path, content, "file", format_type)
    
    @staticmethod
    def rename(old_path: str, new_path: str) -> Dict[str, Any]:
        """
        重命名文件
        
        Args:
            old_path: 原文件路径
            new_path: 新文件路径
            
        Returns:
            重命名结果
        """
        rename_data = {
            "path": new_path
        }
        return client.request(f'/api/contents/{old_path}', 'PATCH', rename_data)
    
    @staticmethod
    def create_directory(dir_path: str) -> Dict[str, Any]:
        """
        创建目录
        
        Args:
            dir_path: 目录路径
            
        Returns:
            创建结果
        """
        dir_data = {
            "type": "directory"
        }
        return client.request(f'/api/contents/{dir_path}', 'PUT', dir_data)


# 导出单例
file_manager = FileManager()
