//! 初始化配置处理器

use axum::{
    extract::State,
    http::StatusCode,
    response::IntoResponse,
    Json,
};
use serde::{Deserialize, Serialize};
use std::sync::Arc;

use crate::models::ApiResponse;
use crate::services::{
    auth::{AuthService, UserRepository},
    AppState,
};

/// 初始化状态响应
#[derive(Debug, Serialize)]
pub struct SetupStatusResponse {
    pub need_setup: bool,
}

/// 初始化请求
#[derive(Debug, Deserialize)]
pub struct SetupInitRequest {
    pub admin_username: String,
    pub admin_password: String,
}

/// 初始化响应
#[derive(Debug, Serialize)]
pub struct SetupInitResponse {
    pub token: String,
    pub message: String,
}

/// 检查是否需要初始化
pub async fn check_setup_status(
    State(state): State<Arc<AppState>>,
) -> impl IntoResponse {
    let repo = UserRepository::new(&state.db);

    // 检查是否存在管理员用户
    let need_setup = match repo.find_all(0, 1).await {
        Ok((users, count)) => count == 0,
        Err(_) => true,
    };

    (
        StatusCode::OK,
        Json(ApiResponse::ok(SetupStatusResponse { need_setup })),
    )
}

/// 执行初始化配置
pub async fn init_setup(
    State(state): State<Arc<AppState>>,
    Json(req): Json<SetupInitRequest>,
) -> impl IntoResponse {
    // 验证输入
    if req.admin_username.len() < 3 {
        return (
            StatusCode::BAD_REQUEST,
            Json(ApiResponse::<SetupInitResponse>::err("用户名至少3个字符")),
        );
    }
    if req.admin_password.len() < 6 {
        return (
            StatusCode::BAD_REQUEST,
            Json(ApiResponse::<SetupInitResponse>::err("密码至少6位")),
        );
    }

    let repo = UserRepository::new(&state.db);

    // 检查是否已经初始化过
    if let Ok((_, count)) = repo.find_all(0, 1).await {
        if count > 0 {
            return (
                StatusCode::BAD_REQUEST,
                Json(ApiResponse::<SetupInitResponse>::err("系统已初始化，请直接登录")),
            );
        }
    }

    // 创建管理员用户
    let (hash, salt) = AuthService::hash_password(&req.admin_password);

    // 先创建普通用户
    let user = match repo.create(&req.admin_username, &hash, &salt, None).await {
        Ok(user) => user,
        Err(e) => {
            return (
                StatusCode::INTERNAL_SERVER_ERROR,
                Json(ApiResponse::<SetupInitResponse>::err(format!("创建用户失败: {}", e))),
            );
        }
    };

    // 将用户设置为管理员
    if let Err(e) = repo.set_role(&user.id, "admin").await {
        return (
            StatusCode::INTERNAL_SERVER_ERROR,
            Json(ApiResponse::<SetupInitResponse>::err(format!("设置管理员失败: {}", e))),
        );
    }

    // 重新获取用户信息
    let admin_user = match repo.find_by_id(&user.id).await {
        Ok(user) => user,
        Err(e) => {
            return (
                StatusCode::INTERNAL_SERVER_ERROR,
                Json(ApiResponse::<SetupInitResponse>::err(format!("获取用户失败: {}", e))),
            );
        }
    };

    // 生成令牌
    let auth_service = AuthService::new(&state.config);
    let token = match auth_service.generate_token(&admin_user) {
        Ok(token) => token,
        Err(e) => {
            return (
                StatusCode::INTERNAL_SERVER_ERROR,
                Json(ApiResponse::<SetupInitResponse>::err(format!("生成令牌失败: {}", e))),
            );
        }
    };

    // 保存配置到文件（可选）
    save_env_config(&req);

    (
        StatusCode::OK,
        Json(ApiResponse::ok(SetupInitResponse {
            token,
            message: "初始化成功！配置已保存到 .env 文件，部分配置需要重启服务后生效。".to_string(),
        })),
    )
}

/// 保存配置到 .env 文件
fn save_env_config(_req: &SetupInitRequest) {
    // 生成随机 JWT Secret
    use std::time::{SystemTime, UNIX_EPOCH};
    let timestamp = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_nanos();
    let jwt_secret = format!("easyremote-jwt-secret-{}", timestamp);

    let env_content = format!(
        r#"# EasyRemote Server Configuration (Auto Generated)

# Server Settings
HOST=0.0.0.0
PORT=9099

# Database Settings
DATABASE_URL=sqlite:easyremote.db?mode=rwc

# JWT Settings
JWT_SECRET={}
JWT_EXPIRY=86400

# STUN/TURN Settings
ENABLE_LOCAL_STUN=true
STUN_PORT=3478
ENABLE_LOCAL_TURN=false
TURN_PORT=3479
TURN_USERNAME=easyremote
TURN_PASSWORD=easyremote123
TURN_REALM=easyremote.local

# Log Level
RUST_LOG=info,tower_http=debug
"#,
        jwt_secret
    );

    // 保存到 .env 文件
    if let Err(e) = std::fs::write(".env", env_content) {
        tracing::warn!("无法保存 .env 文件: {}", e);
    } else {
        tracing::info!("配置已保存到 .env 文件");
    }
}
