//! 笔记模块
//! 
//! 支持阅读笔记、时间统计、导出等功能

use anyhow::Result;
use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc, Duration};
use std::collections::HashMap;

/// 笔记类型
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum NoteType {
    /// 阅读笔记
    Reading,
    /// 想法/灵感
    Idea,
    /// 问题
    Question,
    /// 总结
    Summary,
}

/// 笔记记录
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Note {
    /// 唯一标识
    pub id: String,
    /// 关联文档路径
    pub document_path: String,
    /// 笔记类型
    pub note_type: NoteType,
    /// 笔记内容
    pub content: String,
    /// 关联的页码
    pub page_number: Option<usize>,
    /// 关联的书签 ID
    pub bookmark_id: Option<String>,
    /// 标签
    pub tags: Vec<String>,
    /// 创建时间
    pub created_at: DateTime<Utc>,
    /// 更新时间
    pub updated_at: DateTime<Utc>,
}

impl Note {
    pub fn new(
        document_path: String,
        note_type: NoteType,
        content: String,
    ) -> Self {
        let now = Utc::now();
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            document_path,
            note_type,
            content,
            page_number: None,
            bookmark_id: None,
            tags: Vec::new(),
            created_at: now,
            updated_at: now,
        }
    }
    
    pub fn with_tags(mut self, tags: Vec<String>) -> Self {
        self.tags = tags;
        self.updated_at = Utc::now();
        self
    }
    
    pub fn with_page(mut self, page_number: usize) -> Self {
        self.page_number = Some(page_number);
        self.updated_at = Utc::now();
        self
    }
    
    pub fn with_bookmark(mut self, bookmark_id: String) -> Self {
        self.bookmark_id = Some(bookmark_id);
        self.updated_at = Utc::now();
        self
    }
}

/// 阅读会话记录
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReadingSession {
    /// 文档路径
    pub document_path: String,
    /// 开始时间
    pub start_time: DateTime<Utc>,
    /// 结束时间
    pub end_time: Option<DateTime<Utc>>,
    /// 阅读的页码范围
    pub page_range: Option<(usize, usize)>,
}

impl ReadingSession {
    pub fn start(document_path: String) -> Self {
        Self {
            document_path,
            start_time: Utc::now(),
            end_time: None,
            page_range: None,
        }
    }
    
    pub fn end(mut self, page_range: Option<(usize, usize)>) -> Self {
        self.end_time = Some(Utc::now());
        self.page_range = page_range;
        self
    }
    
    /// 获取阅读时长（秒）
    pub fn duration_seconds(&self) -> i64 {
        let end = self.end_time.unwrap_or(Utc::now());
        (end - self.start_time).num_seconds()
    }
}

/// 阅读统计
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ReadingStats {
    /// 总阅读时长（秒）
    pub total_seconds: i64,
    /// 阅读会话数
    pub session_count: usize,
    /// 笔记数量
    pub note_count: usize,
    /// 书签数量
    pub bookmark_count: usize,
    /// 最后阅读时间
    pub last_read_at: Option<DateTime<Utc>>,
}

/// 笔记管理器
pub struct NoteManager {
    db: sled::Db,
}

impl NoteManager {
    /// 创建笔记管理器
    pub fn new(db_path: &str) -> Result<Self> {
        let db = sled::open(db_path)?;
        Ok(Self { db })
    }
    
    /// 添加笔记
    pub fn add(&self, note: &Note) -> Result<()> {
        let key = format!("note:{}", note.id);
        let value = serde_json::to_vec(note)?;
        self.db.insert(key, value)?;
        Ok(())
    }
    
    /// 删除笔记
    pub fn remove(&self, id: &str) -> Result<()> {
        let key = format!("note:{}", id);
        self.db.remove(key)?;
        Ok(())
    }
    
    /// 更新笔记
    pub fn update(&self, note: &Note) -> Result<()> {
        self.add(note)
    }
    
    /// 获取文档的所有笔记
    pub fn get_by_document(&self, document_path: &str) -> Result<Vec<Note>> {
        let mut notes = Vec::new();
        
        for item in self.db.scan_prefix("note:") {
            let (_, value) = item?;
            let note: Note = serde_json::from_slice(&value)?;
            if note.document_path == document_path {
                notes.push(note);
            }
        }
        
        // 按创建时间排序
        notes.sort_by(|a, b| b.created_at.cmp(&a.created_at));
        
        Ok(notes)
    }
    
    /// 按标签搜索笔记
    pub fn search_by_tag(&self, tag: &str) -> Result<Vec<Note>> {
        let mut notes = Vec::new();
        
        for item in self.db.scan_prefix("note:") {
            let (_, value) = item?;
            let note: Note = serde_json::from_slice(&value)?;
            if note.tags.contains(&tag.to_string()) {
                notes.push(note);
            }
        }
        
        Ok(notes)
    }
    
    /// 记录阅读会话
    pub fn record_session(&self, session: &ReadingSession) -> Result<()> {
        let key = format!("session:{}", session.start_time.timestamp());
        let value = serde_json::to_vec(session)?;
        self.db.insert(key, value)?;
        Ok(())
    }
    
    /// 获取文档的阅读统计
    pub fn get_stats(&self, document_path: &str) -> Result<ReadingStats> {
        let mut stats = ReadingStats::default();
        
        // 统计阅读会话
        let mut total_seconds = 0i64;
        let mut session_count = 0usize;
        let mut last_read_at: Option<DateTime<Utc>> = None;
        
        for item in self.db.scan_prefix("session:") {
            let (_, value) = item?;
            let session: ReadingSession = serde_json::from_slice(&value)?;
            if session.document_path == document_path {
                total_seconds += session.duration_seconds();
                session_count += 1;
                
                let session_end = session.end_time.unwrap_or(session.start_time);
                if last_read_at.is_none() || session_end > last_read_at.unwrap() {
                    last_read_at = Some(session_end);
                }
            }
        }
        
        // 统计笔记
        let note_count = self.get_by_document(document_path)?.len();
        
        // 统计书签（从 bookmark tree 获取）
        let mut bookmark_count = 0usize;
        for item in self.db.scan_prefix("bookmark:") {
            let (_, value) = item?;
            let bookmark: crate::core::bookmark::Bookmark = serde_json::from_slice(&value)?;
            if bookmark.document_path == document_path {
                bookmark_count += 1;
            }
        }
        
        stats.total_seconds = total_seconds;
        stats.session_count = session_count;
        stats.note_count = note_count;
        stats.bookmark_count = bookmark_count;
        stats.last_read_at = last_read_at;
        
        Ok(stats)
    }
    
    /// 导出笔记为 Markdown
    pub fn export_markdown(&self, document_path: &str) -> Result<String> {
        let notes = self.get_by_document(document_path)?;
        let mut md = String::new();
        
        md.push_str(&format!("# {} 笔记导出\n\n", document_path));
        md.push_str(&format!("导出时间：{}\n\n", Utc::now().format("%Y-%m-%d %H:%M:%S")));
        
        // 添加统计信息
        let stats = self.get_stats(document_path)?;
        let hours = stats.total_seconds / 3600;
        let minutes = (stats.total_seconds % 3600) / 60;
        
        md.push_str("## 📊 阅读统计\n\n");
        md.push_str(&format!("- 阅读时长：{}小时{}分钟\n", hours, minutes));
        md.push_str(&format!("- 阅读会话：{}次\n", stats.session_count));
        md.push_str(&format!("- 笔记数量：{}\n", stats.note_count));
        md.push_str(&format!("- 书签数量：{}\n\n", stats.bookmark_count));
        
        if let Some(last_read) = stats.last_read_at {
            md.push_str(&format!("- 最后阅读：{}\n\n", last_read.format("%Y-%m-%d %H:%M:%S")));
        }
        
        md.push_str("---\n\n");
        
        // 按类型分组
        let mut notes_by_type: HashMap<String, Vec<&Note>> = HashMap::new();
        for note in &notes {
            let type_key = match note.note_type {
                NoteType::Reading => "reading",
                NoteType::Idea => "idea",
                NoteType::Question => "question",
                NoteType::Summary => "summary",
            };
            notes_by_type.entry(type_key.to_string())
                .or_insert_with(Vec::new)
                .push(note);
        }
        
        // 输出笔记
        for (type_name, type_notes) in notes_by_type {
            let emoji = match type_name.as_str() {
                "reading" => "📖",
                "idea" => "💡",
                "question" => "❓",
                "summary" => "📝",
                _ => "📌",
            };
            
            md.push_str(&format!("## {} {}\n\n", emoji, type_name.to_uppercase()));
            
            for note in type_notes {
                if let Some(page) = note.page_number {
                    md.push_str(&format!("**页码**: {}  \n", page));
                }
                
                if !note.tags.is_empty() {
                    md.push_str(&format!("**标签**: {}  \n", note.tags.join(", ")));
                }
                
                md.push_str(&format!("\n{}\n\n", note.content));
                md.push_str(&format!("_创建时间：{}_\n\n", note.created_at.format("%Y-%m-%d %H:%M:%S")));
                md.push_str("---\n\n");
            }
        }
        
        Ok(md)
    }
    
    /// 导出笔记为 CSV
    pub fn export_csv(&self, document_path: &str) -> Result<String> {
        let notes = self.get_by_document(document_path)?;
        let mut csv = String::new();
        
        csv.push_str("id,type,page,content,tags,created_at,updated_at\n");
        
        for note in notes {
            let note_type_str = match note.note_type {
                NoteType::Reading => "reading",
                NoteType::Idea => "idea",
                NoteType::Question => "question",
                NoteType::Summary => "summary",
            };
            
            let page = note.page_number.map(|p| p.to_string()).unwrap_or_default();
            let tags = note.tags.join(",");
            let content_escaped = note.content.replace('"', "\"\"");
            
            csv.push_str(&format!(
                "{},{},{},\"{}\",\"{}\",{},{}\n",
                note.id,
                note_type_str,
                page,
                content_escaped,
                tags,
                note.created_at.to_rfc3339(),
                note.updated_at.to_rfc3339()
            ));
        }
        
        Ok(csv)
    }
    
    /// 导出为 Anki 卡片格式
    pub fn export_anki(&self, document_path: &str) -> Result<String> {
        let notes = self.get_by_document(document_path)?;
        let mut anki = String::new();
        
        for note in notes {
            // Anki 导入格式：正面;背面;标签
            let front = match note.note_type {
                NoteType::Question => note.content.clone(),
                _ => format!("{}: {}", 
                    match note.note_type {
                        NoteType::Reading => "阅读笔记",
                        NoteType::Idea => "想法",
                        NoteType::Question => "问题",
                        NoteType::Summary => "总结",
                    },
                    note.content
                ),
            };
            
            let mut back = String::new();
            if let Some(page) = note.page_number {
                back.push_str(&format!("页码：{}\n", page));
            }
            if let Some(bookmark_id) = &note.bookmark_id {
                back.push_str(&format!("关联标注：{}\n", bookmark_id));
            }
            
            let tags = if note.tags.is_empty() {
                "readflow".to_string()
            } else {
                format!("readflow {}", note.tags.join(" "))
            };
            
            anki.push_str(&format!("{};{};{}\n", front, back, tags));
        }
        
        Ok(anki)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_note_creation() {
        let note = Note::new(
            "/path/to/doc.md".to_string(),
            NoteType::Reading,
            "这是一条测试笔记".to_string(),
        );
        
        assert_eq!(note.document_path, "/path/to/doc.md");
        assert!(matches!(note.note_type, NoteType::Reading));
    }
    
    #[test]
    fn test_session_duration() {
        let session = ReadingSession::start("/path/to/doc.md".to_string());
        // 至少应该有 0 秒
        assert!(session.duration_seconds() >= 0);
    }
}
