use erp_auth::dto::CreateUserReq;
use erp_auth::service::user_service::UserService;
use erp_core::events::EventBus;
use erp_core::types::Pagination;

use super::test_db::TestDb;

#[tokio::test]
async fn test_user_crud() {
    let test_db = TestDb::new().await;
    let db = test_db.db();
    let tenant_id = uuid::Uuid::new_v4();
    let operator_id = uuid::Uuid::new_v4();
    let event_bus = EventBus::new(100);

    // 创建用户
    let user = UserService::create(
        tenant_id,
        operator_id,
        &CreateUserReq {
            username: "testuser".to_string(),
            password: "TestPass123".to_string(),
            email: Some("test@example.com".to_string()),
            phone: None,
            display_name: Some("测试用户".to_string()),
        },
        db,
        &event_bus,
    )
    .await
    .expect("创建用户失败");

    assert_eq!(user.username, "testuser");
    assert_eq!(user.status, "active");

    // 按 ID 查询
    let found = UserService::get_by_id(user.id, tenant_id, db)
        .await
        .expect("查询用户失败");
    assert_eq!(found.username, "testuser");
    assert_eq!(found.email, Some("test@example.com".to_string()));

    // 列表查询
    let (users, total) = UserService::list(
        tenant_id,
        &Pagination {
            page: Some(1),
            page_size: Some(10),
        },
        None,
        db,
    )
    .await
    .expect("用户列表查询失败");
    assert_eq!(total, 1);
    assert_eq!(users[0].username, "testuser");
}

#[tokio::test]
async fn test_tenant_isolation() {
    let test_db = TestDb::new().await;
    let db = test_db.db();
    let tenant_a = uuid::Uuid::new_v4();
    let tenant_b = uuid::Uuid::new_v4();
    let operator_id = uuid::Uuid::new_v4();
    let event_bus = EventBus::new(100);

    // 租户 A 创建用户
    let user_a = UserService::create(
        tenant_a,
        operator_id,
        &CreateUserReq {
            username: "user_a".to_string(),
            password: "Pass123456".to_string(),
            email: None,
            phone: None,
            display_name: None,
        },
        db,
        &event_bus,
    )
    .await
    .unwrap();

    // 租户 B 列表查询不应看到租户 A 的用户
    let (users_b, total_b) = UserService::list(
        tenant_b,
        &Pagination {
            page: Some(1),
            page_size: Some(10),
        },
        None,
        db,
    )
    .await
    .unwrap();
    assert_eq!(total_b, 0);
    assert!(users_b.is_empty());

    // 租户 B 通过 ID 查询租户 A 的用户应返回错误
    let result = UserService::get_by_id(user_a.id, tenant_b, db).await;
    assert!(result.is_err());
}

#[tokio::test]
async fn test_username_uniqueness_within_tenant() {
    let test_db = TestDb::new().await;
    let db = test_db.db();
    let tenant_id = uuid::Uuid::new_v4();
    let operator_id = uuid::Uuid::new_v4();
    let event_bus = EventBus::new(100);

    let req = CreateUserReq {
        username: "duplicate".to_string(),
        password: "Pass123456".to_string(),
        email: None,
        phone: None,
        display_name: None,
    };

    // 第一次创建成功
    UserService::create(tenant_id, operator_id, &req, db, &event_bus)
        .await
        .expect("创建用户应成功");

    // 同租户重复用户名应失败
    let result = UserService::create(tenant_id, operator_id, &req, db, &event_bus).await;
    assert!(result.is_err());
}
