use crate::domain::entities::users;
use anyhow::Result;
use sea_orm::{
    ActiveModelTrait, ColumnTrait, ConnectionTrait, DatabaseConnection, EntityTrait,
    PaginatorTrait, QueryFilter, Set,
};

/// 用户数据访问仓库
pub struct UserRepository {
    db: DatabaseConnection,
}

impl UserRepository {
    pub fn new(db: DatabaseConnection) -> Self {
        Self { db }
    }

    /// 根据 email 查询用户
    pub async fn find_by_email(&self, email: &str) -> Result<Option<users::Model>> {
        let user = users::Entity::find()
            .filter(users::Column::Email.eq(email))
            .filter(users::Column::DeletedAt.is_null())
            .one(&self.db)
            .await
            .map_err(|e| anyhow::anyhow!("查询失败: {}", e))?;

        Ok(user)
    }

    pub async fn find_by_id_raw(&self, id: &str) -> Result<Option<users::Model>> {
        Ok(users::Entity::find_by_id(id).one(&self.db).await?)
    }

    /// 统计邮箱数量
    pub async fn count_by_email(&self, email: &str) -> Result<i64> {
        let count = users::Entity::find()
            .filter(users::Column::Email.eq(email))
            .count(&self.db)
            .await
            .map_err(|e| anyhow::anyhow!("查询失败: {}", e))?;

        Ok(count as i64)
    }

    /// 统计用户 ID 数量
    pub async fn count_by_id(&self, id: &str) -> Result<i64> {
        let count = users::Entity::find()
            .filter(users::Column::Id.eq(id))
            .count(&self.db)
            .await
            .map_err(|e| anyhow::anyhow!("查询失败: {}", e))?;

        Ok(count as i64)
    }

    /// 获取密码哈希
    pub async fn get_password_hash(&self, email: &str) -> Result<Option<String>> {
        let user = users::Entity::find()
            .filter(users::Column::Email.eq(email))
            .one(&self.db)
            .await
            .map_err(|e| anyhow::anyhow!("查询失败: {}", e))?;

        Ok(user.map(|u| u.password_hash))
    }

    pub async fn get_password_hash_by_id(&self, id: &str) -> Result<Option<String>> {
        Ok(users::Entity::find_by_id(id)
            .one(&self.db)
            .await?
            .map(|user| user.password_hash))
    }

    /// 使用调用方连接或事务插入用户。
    pub async fn insert_with<C>(
        db: &C,
        id: String,
        email: String,
        password_hash: String,
        role: &str,
    ) -> Result<users::Model>
    where
        C: ConnectionTrait,
    {
        let user_model = users::ActiveModel {
            id: Set(id),
            email: Set(email),
            password_hash: Set(password_hash),
            role: Set(role.into()),
            status: Set("active".into()),
            // created_at 和 updated_at 由 ActiveModelBehavior 自动填充
            ..Default::default()
        };

        let inserted_user = user_model
            .insert(db)
            .await
            .map_err(|e| anyhow::anyhow!("插入失败: {}", e))?;

        Ok(inserted_user)
    }

    pub fn connection(&self) -> DatabaseConnection {
        self.db.clone()
    }

    /// 根据 ID 删除用户
    #[allow(dead_code)]
    pub async fn delete_by_id(&self, id: &str) -> Result<()> {
        let user = users::Entity::find_by_id(id)
            .one(&self.db)
            .await?
            .ok_or_else(|| anyhow::anyhow!("用户不存在"))?;
        let mut active: users::ActiveModel = user.into();
        active.deleted_at = Set(Some(chrono::Utc::now().naive_utc()));
        active.update(&self.db).await?;

        Ok(())
    }

    pub async fn update_password_by_email(&self, email: &str, password_hash: String) -> Result<()> {
        let user = self
            .find_by_email(email)
            .await?
            .ok_or_else(|| anyhow::anyhow!("用户不存在"))?;
        let mut active: users::ActiveModel = user.into();
        active.password_hash = Set(password_hash);
        active.update(&self.db).await?;
        Ok(())
    }
}
