# 标准库导入
import os
import json
import shutil
import logging
from pathlib import Path
from typing import List, Dict, Any, Optional

# 第三方库导入
from fastapi import APIRouter, HTTPException, UploadFile, File, Form
from fastapi.responses import JSONResponse, FileResponse

# 本地模块导入
from models.internal import WorldInfo, WorldInfoEntry
from core.config import settings
from services.worldbook_service import worldbook_service

# 配置日志
logger = logging.getLogger(__name__)

# 创建路由器
router = APIRouter(prefix="/worldbooks", tags=["worldbooks"])

# 确保世界书目录存在 (由 config.py 中的 settings.ensure_directories() 统一处理，此处保留作为双重保险)
os.makedirs(settings.WORLDBOOKS_PATH, exist_ok=True)


@router.get("/", response_model=List[Dict[str, Any]])
async def list_worldbooks():
	"""
	获取所有世界书的列表
	Returns:
		List[Dict[str, Any]]: 世界书列表
	"""
	try:
		return worldbook_service.list_worldbooks()
	except Exception as e:
		logger.error(f"Failed to list worldbooks: {str(e)}")
		raise HTTPException(status_code=500, detail=str(e))

# 注意：路由定义顺序很重要！更具体的路由（更多参数）必须放在前面
@router.get("/{name}/entries/{uid}", response_model=Dict[str, Any])
async def get_worldbook_entry(name: str, uid: str):
	"""
	获取世界书的指定条目
	"""
	try:
		return worldbook_service.get_entry(name, uid)
	except FileNotFoundError as e:
		raise HTTPException(status_code=404, detail=str(e))
	except Exception as e:
		logger.error(f"Failed to get entry '{uid}' from worldbook '{name}': {str(e)}")
		raise HTTPException(status_code=500, detail=str(e))

@router.get("/{name}/entries", response_model=Dict[str, Any])
async def list_worldbook_entries(
    name: str,
    page: int = 1,
    page_size: int = 20
):
	"""
	获取世界书的条目列表（支持分页）
	
	Args:
		name: 世界书名称
		page: 页码，从1开始
		page_size: 每页数量，默认20
	"""
	try:
		return worldbook_service.list_entries(name, page, page_size)
	except FileNotFoundError as e:
		raise HTTPException(status_code=404, detail=str(e))
	except Exception as e:
		logger.error(f"Failed to list entries for worldbook '{name}': {str(e)}")
		raise HTTPException(status_code=500, detail=str(e))

@router.get("/{name}/export")
async def export_worldbook(name: str, format: str = "internal"):
	"""
	导出世界书(支持 internal 和 sillytavern 两种格式)
	
	Args:
		name: 世界书名称
		format: 导出格式 ('internal' 或 'sillytavern'),默认 internal
	"""
	try:
		if format.lower() == "sillytavern":
			# 导出为 SillyTavern 格式(可能丢失特殊设置)
			logger.info(f"导出世界书 '{name}' 为 SillyTavern 格式")
			st_data = worldbook_service.export_to_sillytavern(name)
			
			return JSONResponse(
				content=st_data,
				headers={
					"Content-Disposition": f"attachment; filename={name}_sillytavern.json"
				}
			)
		else:
			# 导出为内部格式(保留所有设置)
			logger.info(f"导出世界书 '{name}' 为内部格式")
			internal_data = worldbook_service.get_worldbook(name)
			
			return JSONResponse(
				content=internal_data,
				headers={
					"Content-Disposition": f"attachment; filename={name}.json"
				}
			)
	except FileNotFoundError as e:
		raise HTTPException(status_code=404, detail=str(e))
	except Exception as e:
		logger.error(f"Failed to export worldbook '{name}': {str(e)}")
		raise HTTPException(status_code=500, detail=str(e))

@router.get("/{name}", response_model=Dict[str, Any])
async def get_worldbook(name: str):
	"""
	获取指定名称的世界书
	"""
	try:
		return worldbook_service.get_worldbook(name)
	except FileNotFoundError as e:
		raise HTTPException(status_code=404, detail=str(e))
	except Exception as e:
		logger.error(f"Failed to get worldbook '{name}': {str(e)}")
		raise HTTPException(status_code=500, detail=str(e))

@router.post("/", response_model=Dict[str, Any])
async def create_worldbook(
		name: str = Form(...),
		description: str = Form(""),
		file: Optional[UploadFile] = File(None)
):
	"""
	创建新世界书（可选择导入文件）
	"""
	try:
		# 如果提供了文件，从 SillyTavern 格式导入
		if file:
			content = await file.read()
			st_data = json.loads(content.decode('utf-8'))
			return worldbook_service.import_from_sillytavern(name, st_data)
		else:
			# 创建空世界书
			return worldbook_service.create_worldbook(name, description)
	except ValueError as e:
		raise HTTPException(status_code=400, detail=str(e))
	except Exception as e:
		logger.error(f"Failed to create worldbook '{name}': {str(e)}")
		raise HTTPException(status_code=500, detail=str(e))

@router.put("/{name}", response_model=Dict[str, Any])
async def update_worldbook(
		name: str,
		description: Optional[str] = Form(None)
):
	"""
	更新世界书基本信息
	"""
	try:
		return worldbook_service.update_worldbook(name, description)
	except FileNotFoundError as e:
		raise HTTPException(status_code=404, detail=str(e))
	except Exception as e:
		logger.error(f"Failed to update worldbook '{name}': {str(e)}")
		raise HTTPException(status_code=500, detail=str(e))

@router.delete("/{name}")
async def delete_worldbook(name: str):
	"""
	删除世界书
	"""
	try:
		worldbook_service.delete_worldbook(name)
		return {"message": f"Worldbook '{name}' deleted successfully"}
	except FileNotFoundError as e:
		raise HTTPException(status_code=404, detail=str(e))
	except Exception as e:
		logger.error(f"Failed to delete worldbook '{name}': {str(e)}")
		raise HTTPException(status_code=500, detail=str(e))

@router.get("/{name}/entries", response_model=Dict[str, Any])
async def list_worldbook_entries(
    name: str,
    page: int = 1,
    page_size: int = 20
):
	"""
	获取世界书的条目列表（支持分页）
	
	Args:
		name: 世界书名称
		page: 页码，从1开始
		page_size: 每页数量，默认20
	"""
	try:
		return worldbook_service.list_entries(name, page, page_size)
	except FileNotFoundError as e:
		raise HTTPException(status_code=404, detail=str(e))
	except Exception as e:
		logger.error(f"Failed to list entries for worldbook '{name}': {str(e)}")
		raise HTTPException(status_code=500, detail=str(e))

@router.get("/{name}/entries/{uid}", response_model=Dict[str, Any])
async def get_worldbook_entry(name: str, uid: str):
	"""
	获取世界书的指定条目
	"""
	try:
		return worldbook_service.get_entry(name, uid)
	except FileNotFoundError as e:
		raise HTTPException(status_code=404, detail=str(e))
	except Exception as e:
		logger.error(f"Failed to get entry '{uid}' from worldbook '{name}': {str(e)}")
		raise HTTPException(status_code=500, detail=str(e))

@router.post("/{name}/entries", response_model=Dict[str, Any])
async def create_worldbook_entry(name: str, entry_data: Dict[str, Any]):
	"""
	在世界书中创建新条目
	"""
	try:
		return worldbook_service.create_entry(name, entry_data)
	except FileNotFoundError as e:
		raise HTTPException(status_code=404, detail=str(e))
	except Exception as e:
		logger.error(f"Failed to create entry in worldbook '{name}': {str(e)}")
		raise HTTPException(status_code=500, detail=str(e))

@router.put("/{name}/entries/{uid}", response_model=Dict[str, Any])
async def update_worldbook_entry(name: str, uid: str, entry_data: Dict[str, Any]):
	"""
	更新世界书的指定条目
	"""
	try:
		return worldbook_service.update_entry(name, uid, entry_data)
	except FileNotFoundError as e:
		raise HTTPException(status_code=404, detail=str(e))
	except Exception as e:
		logger.error(f"Failed to update entry '{uid}' in worldbook '{name}': {str(e)}")
		raise HTTPException(status_code=500, detail=str(e))

@router.delete("/{name}/entries/{uid}")
async def delete_worldbook_entry(name: str, uid: str):
	"""
	删除世界书的指定条目
	"""
	try:
		worldbook_service.delete_entry(name, uid)
		return {"message": f"Entry '{uid}' deleted successfully"}
	except FileNotFoundError as e:
		raise HTTPException(status_code=404, detail=str(e))
	except Exception as e:
		logger.error(f"Failed to delete entry '{uid}' from worldbook '{name}': {str(e)}")
		raise HTTPException(status_code=500, detail=str(e))

@router.post("/{name}/import", response_model=Dict[str, Any])
async def import_worldbook(name: str, file: UploadFile = File(...)):
	"""
	从文件导入世界书(自动检测 SillyTavern 或内部格式)
	"""
	try:
		content = await file.read()
		data = json.loads(content.decode('utf-8'))
		
		# 智能检测格式
		from models.converters import WorldBookConverter
		format_type = WorldBookConverter.detect_format(data)
		
		logger.info(f"检测到世界书格式: {format_type}")
		
		if format_type == "sillytavern":
			# SillyTavern 格式,需要转换
			logger.info(f"正在转换 SillyTavern 格式为内部格式")
			return worldbook_service.import_from_sillytavern(name, data)
		elif format_type == "internal":
			# 已经是内部格式,直接保存
			logger.info(f"检测到内部格式,直接保存")
			return worldbook_service.import_internal_format(name, data)
		else:
			raise HTTPException(status_code=400, detail="无法识别的世界书格式")
			
	except json.JSONDecodeError:
		raise HTTPException(status_code=400, detail="Invalid JSON format")
	except ValueError as e:
		raise HTTPException(status_code=400, detail=str(e))
	except Exception as e:
		logger.error(f"Failed to import worldbook '{name}': {str(e)}")
		raise HTTPException(status_code=500, detail=str(e))
