/**
 * 自然写互动课堂PC端应用软件 V1.0
 * 数据库管理模块 - 基于better-sqlite3实现SQLite本地数据持久化
 * 
 * 功能说明：
 * 1. 数据库初始化与版本迁移（Schema Migration）
 * 2. 学生笔迹数据的存储与检索（支持按学生/作业/时间维度查询）
 * 3. 作业批改记录管理（AI批改 + 人工标注）
 * 4. 班级/学生信息本地缓存（减少网络请求）
 * 5. 点阵码映射关系维护（课件页面与点阵码对应）
 * 6. 课件元数据索引（本地课件文件的管理信息）
 * 7. 数据库文件加密（SQLCipher集成，防止本地数据泄露）
 * 8. 自动备份与数据清理策略
 */

import path from 'path';
import fs from 'fs';
import { app } from 'electron';
import crypto from 'crypto';

/* ========== 类型定义 ========== */

/** 数据库配置接口 */
interface DatabaseConfig {
    dbPath: string;             // 数据库文件路径
    encryptionKey: string;      // 加密密钥（SQLCipher）
    maxBackups: number;         // 最大备份数量
    autoVacuumInterval: number; // 自动整理间隔（毫秒）
    walMode: boolean;           // 是否启用WAL模式
}

/** 学生笔迹记录 */
interface StrokeRecord {
    id: string;
    studentId: string;
    studentName: string;
    assignmentId: string;
    pageIndex: number;
    strokeData: string;        // JSON序列化的笔迹坐标数据
    thumbnailPath: string;     // 缩略图文件路径
    collectTime: number;       // 采集时间戳
    syncStatus: number;        // 同步状态: 0=未同步, 1=已同步, 2=同步失败
    fileSize: number;          // 数据大小（字节）
}

/** 批改记录 */
interface GradeRecord {
    id: string;
    assignmentId: string;
    studentId: string;
    aiScore: number;           // AI评分（0-100）
    teacherScore: number;      // 教师评分（-1表示未批改）
    aiAnnotation: string;      // AI批改标注JSON
    teacherAnnotation: string; // 教师手动标注JSON
    gradeTime: number;
    status: number;            // 0=待批改, 1=AI已批, 2=教师已批
}

/** 班级信息 */
interface ClassInfo {
    classId: string;
    className: string;
    grade: string;
    teacherId: string;
    studentCount: number;
    lastSyncTime: number;
}

/** 学生信息 */
interface StudentInfo {
    studentId: string;
    studentName: string;
    classId: string;
    seatNumber: number;
    penDeviceId: string;       // 绑定的点阵笔设备ID
    avatarPath: string;
}

/** 点阵码映射 */
interface DotCodeMapping {
    dotCodeId: string;         // 点阵码唯一标识
    coursewareId: string;      // 课件ID
    pageIndex: number;         // 对应页面索引
    regionType: string;        // 区域类型: 'answer'/'writing'/'drawing'
    coordinates: string;       // 区域坐标JSON
}

/** 课件元数据 */
interface CoursewareMeta {
    coursewareId: string;
    title: string;
    type: string;              // 'ppt'/'pdf'/'custom'
    filePath: string;          // 本地文件路径
    pageCount: number;
    fileSize: number;
    createTime: number;
    lastOpenTime: number;
    cloudUrl: string;          // 云端地址
    syncStatus: number;
}

/** 迁移脚本定义 */
interface Migration {
    version: number;
    description: string;
    sql: string;
}

/* ========== 数据库管理器 ========== */

// 数据库Schema版本号，每次表结构变更递增
const CURRENT_SCHEMA_VERSION = 5;

/**
 * 数据库管理器 - 统一管理SQLite数据库的生命周期
 * 采用单例模式确保全局唯一数据库连接
 */
class DatabaseManager {
    private db: any = null;                   // better-sqlite3 数据库实例
    private config: DatabaseConfig;            // 数据库配置
    private backupTimer: ReturnType<typeof setInterval> | null = null;
    private vacuumTimer: ReturnType<typeof setInterval> | null = null;
    private initialized: boolean = false;

    constructor() {
        // 默认配置：数据库存储在应用数据目录
        const userDataPath = app.getPath('userData');
        this.config = {
            dbPath: path.join(userDataPath, 'writech_data.db'),
            encryptionKey: this.loadOrCreateEncryptionKey(),
            maxBackups: 5,
            autoVacuumInterval: 24 * 60 * 60 * 1000, // 每24小时整理一次
            walMode: true
        };
    }

    /**
     * 加载或创建数据库加密密钥
     * 密钥存储在操作系统安全凭据管理器中（通过keytar）
     * 首次运行时生成随机256位密钥
     */
    private loadOrCreateEncryptionKey(): string {
        const keyFilePath = path.join(app.getPath('userData'), '.db_key');
        try {
            if (fs.existsSync(keyFilePath)) {
                return fs.readFileSync(keyFilePath, 'utf-8').trim();
            }
            // 生成256位随机密钥并保存
            const newKey = crypto.randomBytes(32).toString('hex');
            fs.writeFileSync(keyFilePath, newKey, { mode: 0o600 });
            console.log('[DatabaseManager] 已生成新的数据库加密密钥');
            return newKey;
        } catch (error) {
            console.error('[DatabaseManager] 密钥管理失败，使用默认密钥:', error);
            return 'writech_default_key_2024';
        }
    }

    /**
     * 初始化数据库连接并执行迁移
     * 启用WAL模式提高并发读写性能
     * 设置SQLCipher加密密钥
     */
    async initialize(): Promise<void> {
        if (this.initialized) return;

        try {
            const Database = require('better-sqlite3');
            const dbDir = path.dirname(this.config.dbPath);
            if (!fs.existsSync(dbDir)) {
                fs.mkdirSync(dbDir, { recursive: true });
            }

            // 创建数据库连接（启用verbose日志用于调试）
            this.db = new Database(this.config.dbPath, { verbose: undefined });

            // 设置SQLCipher加密密钥
            this.db.pragma(`key='${this.config.encryptionKey}'`);

            // 启用WAL模式提高并发性能
            if (this.config.walMode) {
                this.db.pragma('journal_mode=WAL');
                this.db.pragma('synchronous=NORMAL');
            }

            // 启用外键约束
            this.db.pragma('foreign_keys=ON');

            // 执行数据库迁移
            this.runMigrations();

            // 启动定时任务（备份 + 整理）
            this.startAutoBackup();
            this.startAutoVacuum();

            this.initialized = true;
            console.log('[DatabaseManager] 数据库初始化完成，版本:', CURRENT_SCHEMA_VERSION);
        } catch (error) {
            console.error('[DatabaseManager] 数据库初始化失败:', error);
            throw error;
        }
    }

    /**
     * 获取所有迁移脚本列表
     * 每个版本对应一个迁移脚本，按版本号顺序执行
     */
    private getMigrations(): Migration[] {
        return [
            {
                version: 1,
                description: '创建基础表结构',
                sql: `
                    -- 学生笔迹数据表
                    CREATE TABLE IF NOT EXISTS stroke_records (
                        id TEXT PRIMARY KEY,
                        student_id TEXT NOT NULL,
                        student_name TEXT NOT NULL,
                        assignment_id TEXT NOT NULL,
                        page_index INTEGER DEFAULT 0,
                        stroke_data TEXT NOT NULL,
                        thumbnail_path TEXT DEFAULT '',
                        collect_time INTEGER NOT NULL,
                        sync_status INTEGER DEFAULT 0,
                        file_size INTEGER DEFAULT 0,
                        created_at INTEGER DEFAULT (strftime('%s','now'))
                    );
                    CREATE INDEX IF NOT EXISTS idx_stroke_student ON stroke_records(student_id);
                    CREATE INDEX IF NOT EXISTS idx_stroke_assignment ON stroke_records(assignment_id);
                    CREATE INDEX IF NOT EXISTS idx_stroke_time ON stroke_records(collect_time);

                    -- 批改记录表
                    CREATE TABLE IF NOT EXISTS grade_records (
                        id TEXT PRIMARY KEY,
                        assignment_id TEXT NOT NULL,
                        student_id TEXT NOT NULL,
                        ai_score REAL DEFAULT -1,
                        teacher_score REAL DEFAULT -1,
                        ai_annotation TEXT DEFAULT '{}',
                        teacher_annotation TEXT DEFAULT '{}',
                        grade_time INTEGER NOT NULL,
                        status INTEGER DEFAULT 0,
                        created_at INTEGER DEFAULT (strftime('%s','now'))
                    );
                    CREATE INDEX IF NOT EXISTS idx_grade_assignment ON grade_records(assignment_id);
                    CREATE INDEX IF NOT EXISTS idx_grade_student ON grade_records(student_id);
                `
            },
            {
                version: 2,
                description: '添加班级和学生信息表',
                sql: `
                    -- 班级信息缓存表
                    CREATE TABLE IF NOT EXISTS class_info (
                        class_id TEXT PRIMARY KEY,
                        class_name TEXT NOT NULL,
                        grade TEXT DEFAULT '',
                        teacher_id TEXT NOT NULL,
                        student_count INTEGER DEFAULT 0,
                        last_sync_time INTEGER DEFAULT 0
                    );

                    -- 学生信息缓存表
                    CREATE TABLE IF NOT EXISTS student_info (
                        student_id TEXT PRIMARY KEY,
                        student_name TEXT NOT NULL,
                        class_id TEXT NOT NULL,
                        seat_number INTEGER DEFAULT 0,
                        pen_device_id TEXT DEFAULT '',
                        avatar_path TEXT DEFAULT '',
                        FOREIGN KEY (class_id) REFERENCES class_info(class_id)
                    );
                    CREATE INDEX IF NOT EXISTS idx_student_class ON student_info(class_id);
                    CREATE INDEX IF NOT EXISTS idx_student_pen ON student_info(pen_device_id);
                `
            },
            {
                version: 3,
                description: '添加点阵码映射表',
                sql: `
                    -- 点阵码映射关系表（课件页面与点阵码ID对应）
                    CREATE TABLE IF NOT EXISTS dot_code_mapping (
                        dot_code_id TEXT PRIMARY KEY,
                        courseware_id TEXT NOT NULL,
                        page_index INTEGER NOT NULL,
                        region_type TEXT DEFAULT 'answer',
                        coordinates TEXT DEFAULT '{}',
                        created_at INTEGER DEFAULT (strftime('%s','now'))
                    );
                    CREATE INDEX IF NOT EXISTS idx_dotcode_courseware ON dot_code_mapping(courseware_id);
                `
            },
            {
                version: 4,
                description: '添加课件元数据表',
                sql: `
                    -- 课件元数据索引表
                    CREATE TABLE IF NOT EXISTS courseware_meta (
                        courseware_id TEXT PRIMARY KEY,
                        title TEXT NOT NULL,
                        type TEXT DEFAULT 'custom',
                        file_path TEXT NOT NULL,
                        page_count INTEGER DEFAULT 0,
                        file_size INTEGER DEFAULT 0,
                        create_time INTEGER NOT NULL,
                        last_open_time INTEGER DEFAULT 0,
                        cloud_url TEXT DEFAULT '',
                        sync_status INTEGER DEFAULT 0
                    );
                    CREATE INDEX IF NOT EXISTS idx_courseware_type ON courseware_meta(type);
                    CREATE INDEX IF NOT EXISTS idx_courseware_time ON courseware_meta(last_open_time);
                `
            },
            {
                version: 5,
                description: '添加同步日志表用于离线数据追踪',
                sql: `
                    -- 数据同步日志表（记录所有待同步操作）
                    CREATE TABLE IF NOT EXISTS sync_log (
                        id INTEGER PRIMARY KEY AUTOINCREMENT,
                        table_name TEXT NOT NULL,
                        record_id TEXT NOT NULL,
                        operation TEXT NOT NULL,
                        payload TEXT DEFAULT '{}',
                        sync_status INTEGER DEFAULT 0,
                        retry_count INTEGER DEFAULT 0,
                        created_at INTEGER DEFAULT (strftime('%s','now')),
                        synced_at INTEGER DEFAULT 0
                    );
                    CREATE INDEX IF NOT EXISTS idx_sync_status ON sync_log(sync_status);
                `
            }
        ];
    }

    /**
     * 执行数据库迁移
     * 检查当前版本号，依次执行未执行的迁移脚本
     * 使用事务确保迁移的原子性
     */
    private runMigrations(): void {
        // 创建版本跟踪表
        this.db.exec(`
            CREATE TABLE IF NOT EXISTS schema_version (
                version INTEGER PRIMARY KEY,
                description TEXT,
                applied_at INTEGER DEFAULT (strftime('%s','now'))
            );
        `);

        // 获取当前数据库版本
        const row = this.db.prepare('SELECT MAX(version) as ver FROM schema_version').get();
        const currentVersion = row?.ver || 0;

        if (currentVersion >= CURRENT_SCHEMA_VERSION) {
            console.log('[DatabaseManager] 数据库已是最新版本:', currentVersion);
            return;
        }

        // 获取待执行的迁移脚本并按版本排序执行
        const migrations = this.getMigrations().filter(m => m.version > currentVersion);
        const runAll = this.db.transaction(() => {
            for (const migration of migrations) {
                console.log(`[DatabaseManager] 执行迁移 v${migration.version}: ${migration.description}`);
                this.db.exec(migration.sql);
                this.db.prepare('INSERT INTO schema_version (version, description) VALUES (?, ?)')
                    .run(migration.version, migration.description);
            }
        });

        runAll();
        console.log(`[DatabaseManager] 迁移完成: v${currentVersion} -> v${CURRENT_SCHEMA_VERSION}`);
    }

    /* ========== 笔迹数据操作 ========== */

    /** 保存学生笔迹记录（批量插入，提高写入性能） */
    saveStrokeRecords(records: StrokeRecord[]): number {
        const insertStmt = this.db.prepare(`
            INSERT OR REPLACE INTO stroke_records 
            (id, student_id, student_name, assignment_id, page_index, 
             stroke_data, thumbnail_path, collect_time, sync_status, file_size)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        `);

        // 使用事务批量插入，避免逐条写入导致的性能问题
        const insertMany = this.db.transaction((items: StrokeRecord[]) => {
            let count = 0;
            for (const r of items) {
                insertStmt.run(
                    r.id, r.studentId, r.studentName, r.assignmentId,
                    r.pageIndex, r.strokeData, r.thumbnailPath,
                    r.collectTime, r.syncStatus, r.fileSize
                );
                count++;
            }
            // 同时记录同步日志
            const logStmt = this.db.prepare(`
                INSERT INTO sync_log (table_name, record_id, operation, payload)
                VALUES ('stroke_records', ?, 'INSERT', ?)
            `);
            for (const r of items) {
                logStmt.run(r.id, JSON.stringify({ assignmentId: r.assignmentId }));
            }
            return count;
        });

        return insertMany(records);
    }

    /** 按作业ID查询笔迹（支持分页） */
    getStrokesByAssignment(assignmentId: string, page: number = 0, pageSize: number = 50): StrokeRecord[] {
        const offset = page * pageSize;
        return this.db.prepare(`
            SELECT id, student_id as studentId, student_name as studentName,
                   assignment_id as assignmentId, page_index as pageIndex,
                   stroke_data as strokeData, thumbnail_path as thumbnailPath,
                   collect_time as collectTime, sync_status as syncStatus,
                   file_size as fileSize
            FROM stroke_records
            WHERE assignment_id = ?
            ORDER BY collect_time DESC
            LIMIT ? OFFSET ?
        `).all(assignmentId, pageSize, offset);
    }

    /** 查询某学生的所有笔迹（用于学情分析） */
    getStrokesByStudent(studentId: string, startTime?: number, endTime?: number): StrokeRecord[] {
        let sql = `SELECT * FROM stroke_records WHERE student_id = ?`;
        const params: any[] = [studentId];
        if (startTime) {
            sql += ' AND collect_time >= ?';
            params.push(startTime);
        }
        if (endTime) {
            sql += ' AND collect_time <= ?';
            params.push(endTime);
        }
        sql += ' ORDER BY collect_time DESC';
        return this.db.prepare(sql).all(...params);
    }

    /** 获取未同步的笔迹记录（用于断网重连后批量上传） */
    getUnsyncedStrokes(limit: number = 100): StrokeRecord[] {
        return this.db.prepare(`
            SELECT * FROM stroke_records 
            WHERE sync_status = 0 
            ORDER BY collect_time ASC 
            LIMIT ?
        `).all(limit);
    }

    /** 批量更新笔迹同步状态 */
    updateStrokeSyncStatus(ids: string[], status: number): void {
        const placeholders = ids.map(() => '?').join(',');
        this.db.prepare(`
            UPDATE stroke_records SET sync_status = ? 
            WHERE id IN (${placeholders})
        `).run(status, ...ids);
    }

    /* ========== 批改记录操作 ========== */

    /** 保存或更新批改记录 */
    saveGradeRecord(record: GradeRecord): void {
        this.db.prepare(`
            INSERT OR REPLACE INTO grade_records
            (id, assignment_id, student_id, ai_score, teacher_score,
             ai_annotation, teacher_annotation, grade_time, status)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
        `).run(
            record.id, record.assignmentId, record.studentId,
            record.aiScore, record.teacherScore,
            record.aiAnnotation, record.teacherAnnotation,
            record.gradeTime, record.status
        );
    }

    /** 查询作业的批改结果列表 */
    getGradesByAssignment(assignmentId: string): GradeRecord[] {
        return this.db.prepare(`
            SELECT g.*, s.student_name as studentName
            FROM grade_records g
            LEFT JOIN student_info s ON g.student_id = s.student_id
            WHERE g.assignment_id = ?
            ORDER BY g.grade_time DESC
        `).all(assignmentId);
    }

    /** 获取待教师批改的记录数 */
    getPendingGradeCount(): number {
        const row = this.db.prepare(`
            SELECT COUNT(*) as cnt FROM grade_records WHERE status < 2
        `).get();
        return row?.cnt || 0;
    }

    /* ========== 班级/学生信息操作 ========== */

    /** 批量同步班级信息（从云端拉取后缓存到本地） */
    syncClassInfo(classes: ClassInfo[]): void {
        const upsert = this.db.prepare(`
            INSERT OR REPLACE INTO class_info 
            (class_id, class_name, grade, teacher_id, student_count, last_sync_time)
            VALUES (?, ?, ?, ?, ?, ?)
        `);
        const syncAll = this.db.transaction((items: ClassInfo[]) => {
            for (const c of items) {
                upsert.run(c.classId, c.className, c.grade, c.teacherId, c.studentCount, Date.now());
            }
        });
        syncAll(classes);
    }

    /** 批量同步学生信息 */
    syncStudentInfo(students: StudentInfo[]): void {
        const upsert = this.db.prepare(`
            INSERT OR REPLACE INTO student_info
            (student_id, student_name, class_id, seat_number, pen_device_id, avatar_path)
            VALUES (?, ?, ?, ?, ?, ?)
        `);
        const syncAll = this.db.transaction((items: StudentInfo[]) => {
            for (const s of items) {
                upsert.run(s.studentId, s.studentName, s.classId, s.seatNumber, s.penDeviceId, s.avatarPath);
            }
        });
        syncAll(students);
    }

    /** 按班级查询学生列表 */
    getStudentsByClass(classId: string): StudentInfo[] {
        return this.db.prepare(`
            SELECT * FROM student_info WHERE class_id = ? ORDER BY seat_number
        `).all(classId);
    }

    /** 通过点阵笔设备ID查找学生（用于实时笔迹识别） */
    findStudentByPenDevice(penDeviceId: string): StudentInfo | undefined {
        return this.db.prepare(`
            SELECT * FROM student_info WHERE pen_device_id = ?
        `).get(penDeviceId);
    }

    /* ========== 点阵码映射操作 ========== */

    /** 保存点阵码映射关系 */
    saveDotCodeMappings(mappings: DotCodeMapping[]): void {
        const upsert = this.db.prepare(`
            INSERT OR REPLACE INTO dot_code_mapping
            (dot_code_id, courseware_id, page_index, region_type, coordinates)
            VALUES (?, ?, ?, ?, ?)
        `);
        const saveAll = this.db.transaction((items: DotCodeMapping[]) => {
            for (const m of items) {
                upsert.run(m.dotCodeId, m.coursewareId, m.pageIndex, m.regionType, m.coordinates);
            }
        });
        saveAll(mappings);
    }

    /** 根据点阵码ID查找对应的课件页面（笔迹数据落点定位） */
    findPageByDotCode(dotCodeId: string): DotCodeMapping | undefined {
        return this.db.prepare(`
            SELECT * FROM dot_code_mapping WHERE dot_code_id = ?
        `).get(dotCodeId);
    }

    /* ========== 课件元数据操作 ========== */

    /** 保存课件元数据 */
    saveCoursewareMeta(meta: CoursewareMeta): void {
        this.db.prepare(`
            INSERT OR REPLACE INTO courseware_meta
            (courseware_id, title, type, file_path, page_count, file_size,
             create_time, last_open_time, cloud_url, sync_status)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        `).run(
            meta.coursewareId, meta.title, meta.type, meta.filePath,
            meta.pageCount, meta.fileSize, meta.createTime,
            meta.lastOpenTime, meta.cloudUrl, meta.syncStatus
        );
    }

    /** 获取最近打开的课件列表 */
    getRecentCoursewares(limit: number = 20): CoursewareMeta[] {
        return this.db.prepare(`
            SELECT * FROM courseware_meta ORDER BY last_open_time DESC LIMIT ?
        `).all(limit);
    }

    /* ========== 数据库维护操作 ========== */

    /** 启动自动备份定时器（每6小时备份一次） */
    private startAutoBackup(): void {
        const BACKUP_INTERVAL = 6 * 60 * 60 * 1000; // 6小时
        this.backupTimer = setInterval(() => {
            this.createBackup();
        }, BACKUP_INTERVAL);
    }

    /** 创建数据库备份文件 */
    createBackup(): string {
        const backupDir = path.join(path.dirname(this.config.dbPath), 'backups');
        if (!fs.existsSync(backupDir)) {
            fs.mkdirSync(backupDir, { recursive: true });
        }

        // 生成备份文件名（包含时间戳）
        const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
        const backupPath = path.join(backupDir, `writech_backup_${timestamp}.db`);

        // 使用SQLite的backup API执行在线备份（不阻塞读写）
        this.db.backup(backupPath);
        console.log('[DatabaseManager] 数据库备份完成:', backupPath);

        // 清理过期备份（保留最近N个）
        this.cleanOldBackups(backupDir);
        return backupPath;
    }

    /** 清理过期的备份文件 */
    private cleanOldBackups(backupDir: string): void {
        const files = fs.readdirSync(backupDir)
            .filter(f => f.startsWith('writech_backup_'))
            .sort()
            .reverse();

        // 删除超出最大数量的旧备份
        for (let i = this.config.maxBackups; i < files.length; i++) {
            const filePath = path.join(backupDir, files[i]);
            fs.unlinkSync(filePath);
            console.log('[DatabaseManager] 已清理过期备份:', files[i]);
        }
    }

    /** 启动自动数据库整理（VACUUM） */
    private startAutoVacuum(): void {
        this.vacuumTimer = setInterval(() => {
            try {
                // 清理30天前已同步的笔迹原始数据（缩略图保留）
                const threshold = Date.now() - 30 * 24 * 60 * 60 * 1000;
                const result = this.db.prepare(`
                    DELETE FROM stroke_records 
                    WHERE sync_status = 1 AND collect_time < ?
                `).run(threshold);
                if (result.changes > 0) {
                    console.log(`[DatabaseManager] 清理过期笔迹记录: ${result.changes}条`);
                }

                // 清理已同步的同步日志
                this.db.prepare(`
                    DELETE FROM sync_log WHERE sync_status = 1 AND synced_at < ?
                `).run(threshold);

                // 执行VACUUM整理磁盘空间
                this.db.exec('VACUUM');
                console.log('[DatabaseManager] 数据库整理完成');
            } catch (error) {
                console.error('[DatabaseManager] 数据库整理失败:', error);
            }
        }, this.config.autoVacuumInterval);
    }

    /** 获取数据库统计信息（用于状态显示） */
    getStatistics(): Record<string, number> {
        const stats: Record<string, number> = {};
        stats.strokeCount = this.db.prepare('SELECT COUNT(*) as c FROM stroke_records').get().c;
        stats.gradeCount = this.db.prepare('SELECT COUNT(*) as c FROM grade_records').get().c;
        stats.studentCount = this.db.prepare('SELECT COUNT(*) as c FROM student_info').get().c;
        stats.coursewareCount = this.db.prepare('SELECT COUNT(*) as c FROM courseware_meta').get().c;
        stats.unsyncedCount = this.db.prepare('SELECT COUNT(*) as c FROM sync_log WHERE sync_status=0').get().c;

        // 计算数据库文件大小
        try {
            const stat = fs.statSync(this.config.dbPath);
            stats.dbSizeBytes = stat.size;
        } catch {
            stats.dbSizeBytes = 0;
        }
        return stats;
    }

    /** 关闭数据库连接并清理资源 */
    close(): void {
        if (this.backupTimer) {
            clearInterval(this.backupTimer);
            this.backupTimer = null;
        }
        if (this.vacuumTimer) {
            clearInterval(this.vacuumTimer);
            this.vacuumTimer = null;
        }
        if (this.db) {
            // 关闭前执行一次checkpoint确保WAL数据写入
            try { this.db.pragma('wal_checkpoint(TRUNCATE)'); } catch {}
            this.db.close();
            this.db = null;
        }
        this.initialized = false;
        console.log('[DatabaseManager] 数据库连接已关闭');
    }
}

/* ========== 单例导出 ========== */

/** 全局数据库管理器实例 */
const dbManager = new DatabaseManager();
export default dbManager;
