const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const db = require('../db');
const { verifyToken, isSystemAdmin } = require('../middleware/auth');

// 辅助函数：获取所有搜索路径（主目录 + 备用目录）
const getSearchPaths = () => {
    const paths = [];
    
    // 1. 主目录
    const mainDir = process.env.UPLOAD_DIR || 'uploads';
    paths.push(path.isAbsolute(mainDir) ? mainDir : path.join(__dirname, '..', mainDir));
    
    // 2. 备用目录
    if (process.env.UPLOAD_FALLBACK_DIRS) {
        const fallbacks = process.env.UPLOAD_FALLBACK_DIRS.split(',').map(p => p.trim()).filter(p => p);
        fallbacks.forEach(p => {
            const absPath = path.isAbsolute(p) ? p : path.join(__dirname, '..', p);
            // 避免重复
            if (!paths.includes(absPath)) {
                paths.push(absPath);
            }
        });
    }

    // 3. 默认 uploads 目录 (自动兜底)
    // 即使未配置 UPLOAD_FALLBACK_DIRS，也自动查找默认的 uploads 目录，确保旧文件可访问
    const defaultUploads = path.join(__dirname, '..', 'uploads');
    const isDefaultIncluded = paths.some(p => path.resolve(p) === path.resolve(defaultUploads));
    
    if (!isDefaultIncluded) {
        paths.push(defaultUploads);
    }
    
    return paths;
};

// 辅助函数：查找文件（支持多路径回退）
const findFile = (relativePath) => {
    const searchPaths = getSearchPaths();
    for (const rootDir of searchPaths) {
        const fullPath = path.join(rootDir, relativePath);
        if (fs.existsSync(fullPath)) {
            return fullPath;
        }
    }
    return null;
};

// 辅助函数：获取上传根目录的绝对路径 (仅用于写入新文件)
const getUploadRootDir = () => {
    const uploadDir = process.env.UPLOAD_DIR || 'uploads';
    if (path.isAbsolute(uploadDir)) {
        return uploadDir;
    } else {
        return path.join(__dirname, '..', uploadDir);
    }
};

const cleanupUploadedFiles = (files = []) => {
    for (const file of files) {
        if (!file || !file.path) continue;
        try {
            if (fs.existsSync(file.path)) {
                fs.unlinkSync(file.path);
            }
        } catch (e) {
            // Ignore cleanup failure
        }
    }
};

const sanitizeNotificationHtml = (html = '') => {
    return String(html)
        .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
        .replace(/\son\w+\s*=\s*(['"]).*?\1/gi, '')
        .replace(/\son\w+\s*=\s*[^\s>]+/gi, '')
        .replace(/javascript:/gi, '');
};

// 配置 Multer 用于文件上传
const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        const uploadDir = getUploadRootDir();
        // 确保目录存在
        if (!fs.existsSync(uploadDir)) {
            fs.mkdirSync(uploadDir, { recursive: true });
        }
        cb(null, uploadDir);
    },
    filename: (req, file, cb) => {
        const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
        cb(null, 'notify-' + uniqueSuffix + path.extname(file.originalname));
    }
});

const allowedExtensions = [
    '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx',
    '.txt', '.jpg', '.jpeg', '.png', '.zip', '.rar', '.7z'
];

const MAX_NOTIFICATION_FILE_SIZE = Number(process.env.NOTIFY_MAX_FILE_SIZE || 20 * 1024 * 1024);
const MAX_NOTIFICATION_FILES = Number(process.env.NOTIFY_MAX_FILES || 10);

const upload = multer({
    storage: storage,
    limits: {
        fileSize: MAX_NOTIFICATION_FILE_SIZE,
        files: MAX_NOTIFICATION_FILES
    },
    fileFilter: (req, file, cb) => {
        const ext = path.extname(file.originalname).toLowerCase();
        if (allowedExtensions.includes(ext)) {
            cb(null, true);
        } else {
            cb(new Error(`Unsupported file type (${ext}).`));
        }
    }
});

// 获取通知列表 (所有登录用户)
router.get('/', verifyToken, async (req, res) => {
    const { page = 1, limit = 10, keyword } = req.query;
    const offset = (page - 1) * limit;

    try {
        let query = 'SELECT n.*, u.real_name as publisher_real_name FROM notifications n LEFT JOIN users u ON n.publisher_id = u.id WHERE 1=1';
        let countQuery = 'SELECT COUNT(*) FROM notifications WHERE 1=1';
        const params = [];

        if (keyword) {
            query += ` AND (title ILIKE $${params.length + 1} OR content ILIKE $${params.length + 1})`;
            countQuery += ` AND (title ILIKE $${params.length + 1} OR content ILIKE $${params.length + 1})`;
            params.push(`%${keyword}%`);
        }

        query += ` ORDER BY is_top DESC, created_at DESC LIMIT $${params.length + 1} OFFSET $${params.length + 2}`;
        
        const countRes = await db.query(countQuery, params);
        const total = parseInt(countRes.rows[0].count);

        const result = await db.query(query, [...params, limit, offset]);
        
        res.json({
            list: result.rows,
            total,
            page: parseInt(page),
            totalPages: Math.ceil(total / limit)
        });
    } catch (err) {
        console.error(err);
        res.status(500).json({ message: '服务器错误' });
    }
});

// 获取通知详情 (所有登录用户)
router.get('/:id', verifyToken, async (req, res) => {
    const { id } = req.params;
    try {
        const result = await db.query('SELECT n.*, u.real_name as publisher_real_name FROM notifications n LEFT JOIN users u ON n.publisher_id = u.id WHERE n.id = $1', [id]);
        if (result.rows.length === 0) return res.status(404).json({ message: '通知不存在' });
        
        const notification = result.rows[0];
        
        // 获取附件
        const attachmentsRes = await db.query('SELECT * FROM notification_attachments WHERE notification_id = $1', [id]);
        notification.attachments = attachmentsRes.rows;

        res.json(notification);
    } catch (err) {
        console.error(err);
        res.status(500).json({ message: '服务器错误' });
    }
});

// 发布通知 (仅超管和维护员)
router.post('/', verifyToken, isSystemAdmin, (req, res, next) => {
    upload.array('files')(req, res, (err) => {
        if (err) {
            cleanupUploadedFiles(req.files || []);
            return res.status(400).json({ message: err.message });
        }
        next();
    });
}, async (req, res) => {
    const { title, content, is_top } = req.body;
    const files = req.files || [];
    const publisher_id = req.user.id;
    const publisher_name = req.user.real_name || req.user.username;
    const safeContent = sanitizeNotificationHtml(content);

    if (!title || !content || !String(safeContent).trim()) {
        cleanupUploadedFiles(files);
        return res.status(400).json({ message: '标题和内容不能为空' });
    }

    const client = await db.pool.connect();
    try {
        await client.query('BEGIN');

        const result = await client.query(
            'INSERT INTO notifications (title, content, publisher_id, publisher_name, is_top) VALUES ($1, $2, $3, $4, $5) RETURNING id',
            [title, safeContent, publisher_id, publisher_name, is_top === 'true']
        );
        const notificationId = result.rows[0].id;

        // 保存附件
        for (const file of files) {
            let originalName = file.originalname;
            // 简单处理文件名编码问题
            if (!/[^\u0000-\u00ff]/.test(originalName)) {
                try {
                    const decodedName = Buffer.from(originalName, 'latin1').toString('utf8');
                    if (/[\u4e00-\u9fa5]/.test(decodedName)) {
                        originalName = decodedName;
                    }
                } catch (e) {}
            }

            await client.query(
                'INSERT INTO notification_attachments (notification_id, file_name, file_path) VALUES ($1, $2, $3)',
                [notificationId, originalName, file.filename]
            );
        }

        await client.query('COMMIT');
        res.status(201).json({ message: '发布成功', id: notificationId });
    } catch (err) {
        await client.query('ROLLBACK');
        cleanupUploadedFiles(files);
        console.error(err);
        res.status(500).json({ message: '服务器错误' });
    } finally {
        client.release();
    }
});

// 删除通知 (仅超管和维护员)
router.delete('/:id', verifyToken, isSystemAdmin, async (req, res) => {
    const { id } = req.params;
    const client = await db.pool.connect();
    try {
        await client.query('BEGIN');

        // 获取附件并删除文件
        const filesRes = await client.query('SELECT file_path FROM notification_attachments WHERE notification_id = $1', [id]);
        
        for (const row of filesRes.rows) {
            const filePath = findFile(row.file_path);
            if (filePath) {
                try { fs.unlinkSync(filePath); } catch (e) {}
            }
        }

        // 级联删除会自动删除 notification_attachments 表中的记录
        await client.query('DELETE FROM notifications WHERE id = $1', [id]);

        await client.query('COMMIT');
        res.json({ message: '删除成功' });
    } catch (err) {
        await client.query('ROLLBACK');
        console.error(err);
        res.status(500).json({ message: '服务器错误' });
    } finally {
        client.release();
    }
});

// 下载附件
router.get('/attachments/:id/download', verifyToken, async (req, res) => {
    const { id } = req.params;
    try {
        const result = await db.query('SELECT * FROM notification_attachments WHERE id = $1', [id]);
        if (result.rows.length === 0) return res.status(404).json({ message: '附件不存在' });
        
        const attachment = result.rows[0];
        const filePath = findFile(attachment.file_path);
        
        if (!filePath) return res.status(404).json({ message: '文件不存在' });

        const encodedFileName = encodeURIComponent(attachment.file_name);
        res.setHeader('Content-Disposition', `attachment; filename*=UTF-8''${encodedFileName}`);
        res.sendFile(filePath);
    } catch (err) {
        console.error(err);
        res.status(500).json({ message: '服务器错误' });
    }
});

module.exports = router;
