# Copyright (c) 2025, jingrow and contributors
# For license information, please see license.txt

from typing import Dict, Any
from pathlib import Path
import json
import shutil
import jingrow
from jingrow.model.page import Page
from jingrow.utils.path import get_jingrow_root
from jingrow.utils.fs import atomic_write_json


class LocalAiNode(Page):
	"""
	Local Ai Node 页面类型
	在保存时自动同步节点数据到 JSON 文件
	"""
	
	def create(self, data: Dict[str, Any]) -> Dict[str, Any]:
		"""创建节点记录，并同步到 JSON 文件"""
		result = super().create(data)
		if result.get('success'):
			created_data = result.get('data', {})
			if created_data.get('node_type'):
				_sync_node_to_json_file(created_data)
		return result
	
	def update(self, name: str, data: Dict[str, Any]) -> Dict[str, Any]:
		"""更新节点记录，并同步到 JSON 文件"""
		result = super().update(name, data)
		if result.get('success'):
			# 获取更新后的完整数据
			updated_res = self.get(name)
			if updated_res.get('success'):
				updated_data = updated_res.get('data', {})
				if updated_data.get('node_type'):
					_sync_node_to_json_file(updated_data)
		return result
	
	def delete(self, name: str) -> Dict[str, Any]:
		"""删除节点记录，并删除对应的节点文件夹"""
		# 在删除前获取节点数据，以便删除对应的文件夹
		node_res = self.get(name)
		if node_res.get('success'):
			node_data = node_res.get('data', {})
			node_type = node_data.get('node_type')
			if node_type:
				# 删除节点文件夹
				_delete_node_folder(node_type)
		
		# 调用父类的 delete 方法删除记录
		return super().delete(name)


def _sync_node_to_json_file(node_data: Dict[str, Any]) -> bool:
	"""
	将节点数据同步到 JSON 文件（LocalAiNode 类的辅助函数）
	当保存 Local Ai Node 时，自动更新对应的 JSON 文件
	
	Args:
		node_data: 节点数据字典，包含 node_type, node_label, node_icon 等字段
		
	Returns:
		bool: 同步是否成功
	"""
	try:
		node_type = node_data.get('node_type')
		if not node_type:
			return False
		
		# 获取节点目录路径
		jingrow_root = get_jingrow_root()
		nodes_root = jingrow_root / "ai" / "nodes"
		node_dir = nodes_root / node_type
		json_file = node_dir / f"{node_type}.json"
		
		# 确保目录存在
		node_dir.mkdir(parents=True, exist_ok=True)
		
		# 解析 node_schema（可能是字典或 JSON 字符串）
		node_schema = node_data.get('node_schema') or {}
		if isinstance(node_schema, str):
			try:
				node_schema = json.loads(node_schema)
			except (json.JSONDecodeError, TypeError):
				node_schema = {}
		if not isinstance(node_schema, dict):
			node_schema = {}
		
		# 确保 node_schema 中不包含 metadata（如果存在则移除）
		node_schema = {k: v for k, v in node_schema.items() if k != 'metadata'}
		
		# 构建完整的 JSON 文件内容
		json_content = {
			"metadata": {
				"type": node_type,
				"label": node_data.get('node_label') or node_type,
				"icon": node_data.get('node_icon') or "fa-cube",
				"color": node_data.get('node_color') or "#6b7280",
				"description": node_data.get('node_description') or "",
				"group": node_data.get('node_group') or "其他",
				"component_type": node_data.get('node_component') or "GenericNode"
			}
		}
		
		# 合并 node_schema 的所有字段（properties, required, _layout 等）
		# 确保包含完整的 schema 配置
		json_content.update(node_schema)
		
		# 确保必需的字段存在（即使 node_schema 中没有）
		json_content.setdefault("properties", {})
		json_content.setdefault("required", [])
		json_content.setdefault("_layout", {
			"tabs": [{
				"id": "tab_1",
				"label": "基本设置",
				"sections": [{
					"id": "section_1",
					"label": "",
					"columns": [{
						"id": "column_1",
						"label": "",
						"fields": []
					}]
				}]
			}],
			"activeTab": "tab_1"
		})
		
		# 使用原子写入确保数据完整性
		atomic_write_json(json_file, json_content)
		
		return True
	except Exception as e:
		# 静默失败，不影响主流程
		jingrow.log_error("同步节点到 JSON 文件失败", str(e), exc=e)
		return False


def _delete_node_folder(node_type: str) -> bool:
	"""
	删除节点文件夹（LocalAiNode 类的辅助函数）
	当删除 Local Ai Node 时，自动删除对应的节点文件夹
	
	Args:
		node_type: 节点类型，对应文件夹名称
		
	Returns:
		bool: 删除是否成功
	"""
	try:
		if not node_type:
			return False
		
		# 获取节点目录路径
		jingrow_root = get_jingrow_root()
		nodes_root = jingrow_root / "ai" / "nodes"
		node_dir = nodes_root / node_type
		
		# 如果文件夹存在，则删除
		if node_dir.exists() and node_dir.is_dir():
			shutil.rmtree(node_dir)
			return True
		
		return False
	except Exception as e:
		# 静默失败，不影响主流程
		jingrow.log_error("删除节点文件夹失败", str(e), exc=e)
		return False
