//! 封面形象存储模块
//!
//! 管理用户上传的人物照片（抠图后）的本地存储。

use serde::{Deserialize, Serialize};

use crate::storage::engine::{atomic_write_bytes, atomic_write_json, ensure_dir, read_json, StorageError};
use crate::storage::paths::get_cover_avatars_dir;

/// 封面形象记录
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CoverAvatar {
    pub id: String,
    pub name: String,
    /// 抠图后的透明背景图片 URL（七牛云）
    pub image_url: String,
    /// 本地文件路径（相对于项目目录或绝对路径）
    pub local_path: Option<String>,
    pub created_at: String,
}

/// 封面形象列表
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct CoverAvatarsList {
    pub avatars: Vec<CoverAvatar>,
    pub updated_at: String,
}

/// 加载封面形象库
pub fn load_cover_avatars() -> Result<CoverAvatarsList, StorageError> {
    let path = crate::storage::paths::get_cover_avatars_json_path()?;
    Ok(read_json(&path)?.unwrap_or_default())
}

/// 保存封面形象库
pub fn save_cover_avatars(list: &CoverAvatarsList) -> Result<(), StorageError> {
    let path = crate::storage::paths::get_cover_avatars_json_path()?;
    atomic_write_json(&path, list)
}

/// 添加封面形象
pub fn add_cover_avatar(avatar: CoverAvatar) -> Result<(), StorageError> {
    let mut list = load_cover_avatars()?;
    // 去重：相同 id 替换
    if let Some(pos) = list.avatars.iter().position(|a| a.id == avatar.id) {
        list.avatars[pos] = avatar;
    } else {
        list.avatars.push(avatar);
    }
    list.updated_at = chrono_lite_now();
    save_cover_avatars(&list)
}

/// 删除封面形象
pub fn delete_cover_avatar(id: &str) -> Result<(), StorageError> {
    let mut list = load_cover_avatars()?;
    let pos = list.avatars.iter().position(|a| a.id == id)
        .ok_or_else(|| StorageError::Io(std::io::Error::new(
            std::io::ErrorKind::NotFound,
            format!("封面形象 {} 不存在", id),
        )))?;
    list.avatars.remove(pos);
    list.updated_at = chrono_lite_now();
    save_cover_avatars(&list)
}

/// 保存封面形象图片文件到本地
///
/// 将 base64 编码的图片数据写入 `cover_avatars/` 子目录。
pub fn save_cover_avatar_image(
    avatar_id: &str,
    data: &[u8],
    ext: &str,
) -> Result<String, StorageError> {
    let avatars_dir = get_cover_avatars_dir()?;
    ensure_dir(&avatars_dir)?;

    // 净化扩展名：只允许字母数字，防止路径遍历
    let safe_ext = ext
        .chars()
        .filter(|c| c.is_alphanumeric())
        .collect::<String>();
    if safe_ext.is_empty() {
        return Err(StorageError::InvalidId("无效的文件扩展名".into()));
    }

    let file_name = format!("{}.{}", avatar_id, safe_ext);
    let file_path = avatars_dir.join(&file_name);

    atomic_write_bytes(&file_path, data)?;

    Ok(file_path.to_str().unwrap_or_default().to_string())
}

// ====================== 工具函数 ======================

fn chrono_lite_now() -> String {
    chrono::Utc::now().to_rfc3339()
}
