//! 书库管理模块
//! 
//! 管理最近阅读、书库文件、缩略图等

use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs;
use std::path::{Path, PathBuf};

/// 书库项目
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct LibraryItem {
    pub path: String,
    pub title: String,
    pub format: String,
    pub file_size: u64,
    pub last_read: Option<i64>, // Unix timestamp
    pub progress: f32, // 0.0 - 1.0
    pub thumbnail: Option<Vec<u8>>,
}

impl LibraryItem {
    pub fn from_path(path: &Path) -> Option<Self> {
        let path_str = path.to_str()?;
        let metadata = fs::metadata(path).ok()?;
        let file_size = metadata.len();
        
        // 检测文件格式
        let extension = path.extension()?.to_str()?.to_lowercase();
        let format = match extension.as_str() {
            "pdf" => "PDF",
            "epub" => "EPUB",
            "mobi" => "MOBI",
            "azw3" => "AZW3",
            "txt" => "TXT",
            "md" => "Markdown",
            _ => return None,
        };
        
        // 提取标题（从文件名）
        let title = path
            .file_stem()?
            .to_str()?
            .to_string();
        
        Some(Self {
            path: path_str.to_string(),
            title,
            format: format.to_string(),
            file_size,
            last_read: None,
            progress: 0.0,
            thumbnail: None,
        })
    }
    
    pub fn format_file_size(&self) -> String {
        if self.file_size < 1024 {
            format!("{} B", self.file_size)
        } else if self.file_size < 1024 * 1024 {
            format!("{:.1} KB", self.file_size as f64 / 1024.0)
        } else if self.file_size < 1024 * 1024 * 1024 {
            format!("{:.1} MB", self.file_size as f64 / (1024.0 * 1024.0))
        } else {
            format!("{:.1} GB", self.file_size as f64 / (1024.0 * 1024.0 * 1024.0))
        }
    }
    
    pub fn format_progress(&self) -> String {
        format!("{}%", (self.progress * 100.0) as i32)
    }
}

/// 书库
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Library {
    #[serde(default)]
    items: HashMap<String, LibraryItem>,
    #[serde(default)]
    library_path: PathBuf,
    #[serde(default)]
    recent_files: Vec<String>, // 最近阅读的文件路径
    max_recent: usize,
}

impl Library {
    pub fn new(library_path: PathBuf) -> Self {
        let mut library = Self {
            items: HashMap::new(),
            library_path,
            recent_files: Vec::new(),
            max_recent: 20,
        };
        // 创建时自动扫描书库
        library.scan_library();
        library
    }
    
    /// 扫描书库目录
    pub fn scan_library(&mut self) -> usize {
        let mut count = 0;
        
        if let Ok(entries) = fs::read_dir(&self.library_path) {
            for entry in entries.flatten() {
                let path = entry.path();
                if path.is_file() {
                    if let Some(item) = LibraryItem::from_path(&path) {
                        let path_str = path.to_string_lossy().to_string();
                        self.items.insert(path_str, item);
                        count += 1;
                    }
                }
            }
        }
        
        count
    }
    
    /// 添加文件到书库
    pub fn add_file(&mut self, path: &Path) -> Result<(), String> {
        if let Some(mut item) = LibraryItem::from_path(path) {
            let path_str = path.to_string_lossy().to_string();
            self.items.insert(path_str.clone(), item);
            self.mark_as_read(&path_str);
            Ok(())
        } else {
            Err("不支持的文件格式".to_string())
        }
    }
    
    /// 标记为已读
    pub fn mark_as_read(&mut self, path: &str) {
        let now = chrono::Local::now().timestamp();
        
        // 更新最后阅读时间
        if let Some(item) = self.items.get_mut(path) {
            item.last_read = Some(now);
        }
        
        // 添加到最近阅读
        self.recent_files.retain(|p| p != path);
        self.recent_files.insert(0, path.to_string());
        
        // 限制最近阅读数量
        if self.recent_files.len() > self.max_recent {
            self.recent_files.truncate(self.max_recent);
        }
    }
    
    /// 获取所有项目
    pub fn get_all_items(&self) -> Vec<&LibraryItem> {
        self.items.values().collect()
    }
    
    /// 获取最近阅读
    pub fn get_recent(&self, limit: usize) -> Vec<&LibraryItem> {
        self.recent_files
            .iter()
            .filter_map(|path| self.items.get(path))
            .take(limit)
            .collect()
    }
    
    /// 搜索文件
    pub fn search(&self, query: &str) -> Vec<&LibraryItem> {
        let query_lower = query.to_lowercase();
        self.items
            .values()
            .filter(|item| {
                item.title.to_lowercase().contains(&query_lower)
                    || item.path.to_lowercase().contains(&query_lower)
            })
            .collect()
    }
    
    /// 保存书库到文件
    pub fn save(&self) -> Result<(), String> {
        let library_dir = self.library_path.join(".readflow");
        fs::create_dir_all(&library_dir).map_err(|e| format!("创建目录失败: {}", e))?;
        
        let library_file = library_dir.join("library.json");
        let json = serde_json::to_string_pretty(self).map_err(|e| format!("序列化失败: {}", e))?;
        fs::write(library_file, json).map_err(|e| format!("写入文件失败: {}", e))?;
        
        Ok(())
    }
    
    /// 从文件加载书库
    pub fn load(&mut self) -> Result<(), String> {
        let library_dir = self.library_path.join(".readflow");
        let library_file = library_dir.join("library.json");
        
        if library_file.exists() {
            let content = fs::read_to_string(library_file).map_err(|e| format!("读取文件失败: {}", e))?;
            let loaded: Library = serde_json::from_str(&content).map_err(|e| format!("反序列化失败: {}", e))?;
            
            self.items = loaded.items;
            self.recent_files = loaded.recent_files;
        }
        
        Ok(())
    }
}