use crate::AppService;
use crate::error::AppError;
use crate::project::audit::AuditLogParams;
use chrono::Utc;
use models::projects::{MemberRole, project};
use sea_orm::prelude::Expr;
use sea_orm::*;
use serde_json::json;
use session::Session;

impl AppService {
    pub async fn project_avatar_upload(
        &self,
        ctx: &Session,
        project_name: String,
        file: Vec<u8>,
        file_ext: String,
    ) -> Result<String, AppError> {
        let user_uid = ctx.user().ok_or(AppError::Unauthorized)?;
        let project = self
            .utils_find_project_by_name(project_name.clone())
            .await?;
        let role = self
            .utils_project_context_role(&ctx, project_name.clone())
            .await?;
        if role == MemberRole::Member {
            return Err(AppError::NoPower);
        }
        let time = Utc::now().timestamp();
        let file_name = format!("{}-{}", project.id, time);
        self.avatar
            .upload(file, file_name.clone(), &file_ext)
            .await
            .map_err(|e| AppError::AvatarUploadError(e.to_string()))?;
        let static_url = self.config.static_domain().unwrap_or("/static".to_string());
        let file_url = format!(
            "{}/avatar/{}",
            static_url.trim_end_matches('/'),
            format!("{}.{}", file_name, file_ext)
        );
        project::Entity::update_many()
            .filter(project::Column::Id.eq(project.id))
            .col_expr(project::Column::AvatarUrl, Expr::value(file_url.clone()))
            .exec(&self.db)
            .await?;
        self.project_log_audit(
            project_name,
            AuditLogParams {
                action: "update avatar".to_string(),
                details: Some(json!({
                    "file_name": file_name,
                    "file_url": file_url,
                    "project_name": project.name,
                    "project_uid": project.id,
                    "user_uid": user_uid,
                })),
            },
            ctx,
        )
        .await?;
        Ok(file_url)
    }
}
