//! router.rs

use crate::response::File;
use crate::response::IntoResponse;
use hyper::body::to_bytes;
use hyper::{Body, Method, Request, Response, StatusCode};
use serde::de::DeserializeOwned;
use serde_json::from_slice as serde_from_json;
use serde_urlencoded::{from_bytes as serde_from_bytes, from_str as serde_from_str};
use std::collections::HashMap;
use std::fs;
use std::future::Future;
use std::path::Path;
use std::pin::Pin;
use std::sync::Arc;

type HandlerFuture = Pin<Box<dyn Future<Output = Response<Body>> + Send>>;
type HandlerFn = Box<dyn Fn(Request<Body>) -> HandlerFuture + Send + Sync>;

/// 路由处理器
pub struct Router {
	routes: HashMap<(Method, String), HandlerFn>,
}

impl Router {
	/// 创建新的路由器
	pub fn new() -> Self {
		Self {
			routes: HashMap::new(),
		}
		.visit_dirs(Path::new("./static"))
	}

	fn visit_dirs(mut self, dir: &Path) -> Self {
		if dir.is_dir() {
			if let Ok(entries) = fs::read_dir(dir) {
				for entry in entries {
					if let Ok(entry) = entry {
						let path = entry.path();
						if path.is_dir() {
							self = self.visit_dirs(&path); // 递归子目录
						} else {
							// 在这里处理文件，例如打印路径
							let p = path
								.to_str()
								.unwrap_or("")
								.to_string()
								.chars()
								.skip(2)
								.collect::<String>();
							self = self.file(format!("/{p}").as_str(), p);
						}
					}
				}
			}
		}
		self
	}

	/// 添加路由
	pub fn route(mut self, path: &str, method_handler: MethodHandler) -> Self {
		self.routes.insert(
			(method_handler.method, path.to_string()),
			method_handler.handler,
		);
		self
	}

	pub fn file(self, path: &str, file_path: String) -> Self {
		let file_path = Arc::new(file_path); // 在外面创建 Arc

		self.route(
			path,
			get(move |query| {
				let file_path = Arc::clone(&file_path);
				async move {
					match query
						.get("download")
						.unwrap_or(&"false".to_string())
						.as_str()
					{
						"1" | "" | "true" => File(file_path.to_string(), true),
						_ => File(file_path.to_string(), false),
					}
				}
			}),
		)
	}

	/// 处理传入的请求
	pub(crate) async fn handle_request(&self, req: Request<Body>) -> Response<Body> {
		let key = (req.method().clone(), req.uri().path().to_string());

		match self.routes.get(&key) {
			Some(handler) => handler(req).await,
			None => Response::builder()
				.status(StatusCode::NOT_FOUND)
				.body(Body::from("404 Not Found"))
				.unwrap(),
		}
	}
}

impl Default for Router {
	fn default() -> Self {
		Self::new()
	}
}

/// 方法处理器构建器
pub struct MethodHandler {
	pub(crate) method: Method,
	pub(crate) handler: HandlerFn,
}

/// 创建 GET 路由
pub fn get<F, Fut, Res>(handler: F) -> MethodHandler
where
	F: Fn(HashMap<String, String>) -> Fut + Send + Sync + 'static,
	Fut: Future<Output = Res> + Send + 'static,
	Res: IntoResponse + 'static,
{
	let handler_fn =
		Box::new(
			move |req: Request<Body>| match serde_from_str(req.uri().query().unwrap_or("")) {
				Ok(query) => {
					let fut = handler(query);
					Box::pin(async move { fut.await.into_response() }) as HandlerFuture
				}
				Err(e) => Box::pin(async move {
					Response::new(Body::from(format!("{:?}<br />Invalid query parameters", e)))
				}) as HandlerFuture,
			},
		);

	MethodHandler {
		method: Method::GET,
		handler: handler_fn,
	}
}

/// 创建 POST 路由
pub fn post<F, Fut, Res>(handler: F) -> MethodHandler
where
	F: Fn(HashMap<String, String>) -> Fut + Send + Sync + 'static,
	Fut: Future<Output = Res> + Send + 'static,
	Res: IntoResponse + 'static,
{
	let handler = Arc::new(handler);
	let handler_fn = Box::new(move |req: Request<Body>| {
		let handler = Arc::clone(&handler);
		Box::pin(async move {
			handler(
				serde_from_bytes(&to_bytes(req.into_body()).await.unwrap_or_default())
					.unwrap_or_default(),
			)
			.await
			.into_response()
		}) as HandlerFuture
	});

	MethodHandler {
		method: Method::POST,
		handler: handler_fn,
	}
}

/// 创建 POST JSON 路由
pub fn post_json<F, Fut, Res, T>(handler: F) -> MethodHandler
where
	F: Fn(T) -> Fut + Send + Sync + 'static,
	Fut: Future<Output = Res> + Send + 'static,
	Res: IntoResponse + 'static,
	T: DeserializeOwned + Send + 'static,
{
	let handler = Arc::new(handler);
	let handler_fn = Box::new(move |req: Request<Body>| {
		let handler = Arc::clone(&handler);
		Box::pin(async move {
			// 读取 body
			let body_bytes = match to_bytes(req.into_body()).await {
				Ok(bytes) => bytes,
				Err(e) => {
					return Response::builder()
						.status(StatusCode::BAD_REQUEST)
						.body(Body::from(format!("读取请求体失败: {}", e)))
						.unwrap();
				}
			};

			// 解析 JSON
			match serde_from_json::<T>(&body_bytes) {
				Ok(data) => handler(data).await.into_response(),
				Err(e) => Response::builder()
					.status(StatusCode::BAD_REQUEST)
					.body(Body::from(format!("无效的 JSON 格式: {}", e)))
					.unwrap(),
			}
		}) as HandlerFuture
	});

	MethodHandler {
		method: Method::POST,
		handler: handler_fn,
	}
}
