from pathlib import Path
import json
import os
import tempfile
import requests
from urllib.parse import urlparse
import jingrow
from jingrow.config import Config
from jingrow.utils.path import get_files_dir

def ensure_dir(path: Path) -> None:
	"""幂等创建目录"""
	path.mkdir(parents=True, exist_ok=True)


def atomic_write_json(target: Path, data: dict, indent: int = 2) -> None:
	"""以原子方式写入JSON。确保UTF-8、缩进与落盘安全替换。"""
	ensure_dir(target.parent)
	with tempfile.NamedTemporaryFile('w', delete=False, dir=str(target.parent), encoding='utf-8') as tmp:
		json.dump(data, tmp, ensure_ascii=False, indent=indent)
		tmp.flush()
		os.fsync(tmp.fileno())
		tmp_name = tmp.name
	os.replace(tmp_name, target)


@jingrow.whitelist(allow_guest=True)
def download_image_to_local(image_url: str, filename: str = None) -> dict:
	"""
	异步下载图片到本地文件存储目录（apps/jingrow/jingrow/public/files）
	
	Args:
		image_url (str): 图片URL
		filename (str, optional): 本地文件名，如果不提供则从URL中提取
	
	Returns:
		dict: 下载结果
		{
			'success': bool,
			'local_path': str,  # 成功时返回本地文件路径
			'cached': bool,     # 是否使用了缓存（文件已存在）
			'error': str        # 失败时返回错误信息
		}
	"""
	try:
		# 处理相对URL，转换为完整URL
		if image_url.startswith('/'):
			# 相对路径，需要拼接Jingrow服务器URL
			if image_url.startswith('/files/'):
				image_url = f"{Config.jingrow_server_url}{image_url}"
			else:
				image_url = f"{Config.jingrow_server_url}{image_url}"
		
		# 解析URL获取文件名
		if not filename:
			parsed_url = urlparse(image_url)
			filename = os.path.basename(parsed_url.path)
			if not filename or '.' not in filename:
				filename = f"image_{hash(image_url) % 100000}.jpg"
		
		# 确保文件名安全
		filename = "".join(c for c in filename if c.isalnum() or c in "._-")
		
		# 构建本地文件路径
		public_dir = get_files_dir()
		ensure_dir(public_dir)
		local_path = public_dir / filename
		
		# 检查文件是否已存在
		if local_path.exists():
			return {
				'success': True,
				'local_path': str(local_path),
				'cached': True,
				'file_size': local_path.stat().st_size
			}
		
		# 下载图片
		response = requests.get(image_url, timeout=30)
		response.raise_for_status()
		
		# 保存到本地
		with open(local_path, 'wb') as f:
			f.write(response.content)
		
		return {
			'success': True,
			'local_path': str(local_path),
			'cached': False,
			'file_size': len(response.content)
		}
		
	except Exception as e:
		return {
			'success': False,
			'error': f'下载图片失败: {str(e)}'
		}


