//! HTTP 文件服务端

use axum::{
    extract::DefaultBodyLimit,
    routing::{get, post},
    Router,
};
use axum_server::tls_rustls::RustlsConfig;
use std::net::SocketAddr;
use std::path::PathBuf;
use tower_http::cors::{Any, CorsLayer};

use crate::tls::CertificateManager;
use crate::utils::AppError;

use super::handlers::{
    download_handler, file_info_handler, health_handler, upload_handler, AppState,
};

/// HTTP 文件服务端
pub struct HttpServer {
    /// 监听端口
    port: u16,
    /// 应用状态
    state: AppState,
    /// 停止信号
    stop_tx: Option<tokio::sync::oneshot::Sender<()>>,
}

impl HttpServer {
    /// 创建新的 HTTP 服务端
    pub fn new(port: u16, download_dir: PathBuf, local_device_id: String) -> Self {
        Self {
            port,
            state: AppState::new(download_dir, local_device_id),
            stop_tx: None,
        }
    }

    /// 获取应用状态
    pub fn state(&self) -> &AppState {
        &self.state
    }

    /// 获取可克隆的状态
    pub fn state_clone(&self) -> AppState {
        self.state.clone()
    }

    /// 启动服务
    pub async fn start(&mut self) -> Result<(), AppError> {
        // 获取 TLS 证书
        let cert_bundle = CertificateManager::get()
            .ok_or_else(|| AppError::Tls("Certificate not initialized".to_string()))?;

        // 创建临时证书文件用于 axum-server
        let temp_dir = std::env::temp_dir().join("flash-send-certs");
        std::fs::create_dir_all(&temp_dir)?;
        
        let cert_path = temp_dir.join("cert.pem");
        let key_path = temp_dir.join("key.pem");
        
        std::fs::write(&cert_path, &cert_bundle.cert_pem)?;
        std::fs::write(&key_path, &cert_bundle.key_pem)?;

        // 配置 TLS
        let tls_config = RustlsConfig::from_pem_file(&cert_path, &key_path)
            .await
            .map_err(|e| AppError::Tls(format!("Failed to load TLS config: {}", e)))?;

        // CORS 配置
        let cors = CorsLayer::new()
            .allow_origin(Any)
            .allow_methods(Any)
            .allow_headers(Any);

        // 创建路由
        let app = Router::new()
            .route("/health", get(health_handler))
            .route("/upload", post(upload_handler))
            .route("/file/:id", get(download_handler))
            .route("/file/:id/info", get(file_info_handler))
            .layer(cors)
            .layer(DefaultBodyLimit::max(10 * 1024 * 1024 * 1024)) // 10GB 限制
            .with_state(self.state.clone());

        // 绑定地址
        let addr = SocketAddr::from(([0, 0, 0, 0], self.port));
        
        log::info!("HTTP server started on https://0.0.0.0:{}", self.port);

        // 创建停止信号
        let (stop_tx, stop_rx) = tokio::sync::oneshot::channel();
        self.stop_tx = Some(stop_tx);

        // 启动服务器
        tokio::spawn(async move {
            let server = axum_server::bind_rustls(addr, tls_config)
                .serve(app.into_make_service());

            tokio::select! {
                result = server => {
                    if let Err(e) = result {
                        log::error!("HTTP server error: {}", e);
                    }
                }
                _ = stop_rx => {
                    log::info!("HTTP server stopping");
                }
            }
        });

        Ok(())
    }

    /// 停止服务
    pub fn stop(&mut self) {
        if let Some(stop_tx) = self.stop_tx.take() {
            let _ = stop_tx.send(());
        }
    }

    /// 注册文件供下载
    pub fn register_file(
        &self,
        file_id: String,
        path: PathBuf,
        name: String,
        size: u64,
        mime_type: String,
    ) {
        use crate::models::FileMetadata;
        
        let metadata = FileMetadata {
            file_id: file_id.clone(),
            name,
            size,
            mime_type,
            thumbnail: None,
            path: Some(path.to_string_lossy().to_string()),
        };
        
        self.state.register_file(file_id, path, metadata);
    }

    /// 移除文件注册
    pub fn unregister_file(&self, file_id: &str) {
        self.state.unregister_file(file_id);
    }
}
