const express = require('express');
const path = require('path');
const fs = require('fs');
const pool = require('../db');
const { requireAuth, requireGroup } = require('../middleware/auth');
const logAudit = require('../helpers/auditLog');

function createKnowledgeBaseRouter(upload) {
  const router = express.Router();

  // Helper to sanitize filename
  function sanitizePathSegment(segment) {
    if (!segment || typeof segment !== 'string') return '';
    return segment
      .replace(/\0/g, '')
      .replace(/\.\./g, '')
      .replace(/[\/\\]/g, '')
      .trim();
  }

  // Helper to generate slug from title
  function generateSlug(title) {
    return title
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, '-')
      .replace(/^-+|-+$/g, '')
      .substring(0, 200);
  }

  // Helper to validate file type
  const ALLOWED_EXTENSIONS = new Set([
    '.pdf', '.md', '.txt', '.doc', '.docx',
    '.xls', '.xlsx', '.ppt', '.pptx',
    '.html', '.htm', '.json', '.yaml', '.yml',
    '.png', '.jpg', '.jpeg', '.gif'
  ]);

  function isValidFileType(filename) {
    const ext = path.extname(filename).toLowerCase();
    return ALLOWED_EXTENSIONS.has(ext);
  }

  // POST /api/knowledge-base/upload
  router.post('/upload', requireAuth(), requireGroup('Admin', 'Standard_User'), (req, res, next) => {
    upload.single('file')(req, res, (err) => {
      if (err) {
        console.error('[KB Upload] Multer error:', err);
        return res.status(400).json({ error: err.message || 'File upload failed' });
      }
      next();
    });
  }, async (req, res) => {
    console.log('[KB Upload] Request received:', {
      hasFile: !!req.file,
      body: req.body,
      contentType: req.headers['content-type']
    });

    const uploadedFile = req.file;
    const { title, description, category } = req.body;

    if (!title || !title.trim()) {
      console.error('[KB Upload] Error: Title is missing');
      if (uploadedFile) fs.unlinkSync(uploadedFile.path);
      return res.status(400).json({ error: 'Title is required' });
    }

    if (!uploadedFile) {
      return res.status(400).json({ error: 'No file uploaded' });
    }

    if (!isValidFileType(uploadedFile.originalname)) {
      fs.unlinkSync(uploadedFile.path);
      return res.status(400).json({ error: 'File type not allowed' });
    }

    const timestamp = Date.now();
    const sanitizedName = sanitizePathSegment(uploadedFile.originalname);
    const slug = generateSlug(title);
    const kbDir = path.join(__dirname, '..', 'uploads', 'knowledge_base');

    const filename = `${timestamp}_${sanitizedName}`;
    const filePath = path.join(kbDir, filename);

    try {
      // Check if slug already exists
      const { rows: existingRows } = await pool.query(
        'SELECT id FROM knowledge_base WHERE slug = $1', [slug]
      );

      const finalSlug = existingRows.length > 0 ? `${slug}-${timestamp}` : slug;

      // Insert new knowledge base entry
      const { rows } = await pool.query(
        `INSERT INTO knowledge_base (
          title, slug, description, category, file_path, file_name,
          file_type, file_size, created_by
        ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
        RETURNING id`,
        [
          title.trim(),
          finalSlug,
          description || null,
          category || 'General',
          filePath,
          sanitizedName,
          uploadedFile.mimetype,
          uploadedFile.size,
          req.user.id
        ]
      );

      // DB insert succeeded — now move file to permanent location
      try {
        if (!fs.existsSync(kbDir)) {
          fs.mkdirSync(kbDir, { recursive: true });
        }
        fs.renameSync(uploadedFile.path, filePath);
      } catch (moveErr) {
        console.error('Error moving file to permanent location:', moveErr);
      }

      logAudit({
        userId: req.user.id,
        username: req.user.username,
        action: 'CREATE_KB_ARTICLE',
        entityType: 'knowledge_base',
        entityId: String(rows[0].id),
        details: { title: title.trim(), filename: sanitizedName },
        ipAddress: req.ip
      });

      res.json({
        success: true,
        id: rows[0].id,
        title: title.trim(),
        slug: finalSlug,
        category: category || 'General'
      });
    } catch (error) {
      if (uploadedFile && fs.existsSync(uploadedFile.path)) fs.unlinkSync(uploadedFile.path);
      console.error('Error uploading knowledge base document:', error);
      res.status(500).json({ error: error.message || 'Failed to upload document' });
    }
  });

  // GET /api/knowledge-base
  router.get('/', requireAuth(), async (req, res) => {
    try {
      const { rows } = await pool.query(`
        SELECT
          kb.id, kb.title, kb.slug, kb.description, kb.category,
          kb.file_name, kb.file_type, kb.file_size, kb.created_at, kb.updated_at,
          u.username as created_by_username
        FROM knowledge_base kb
        LEFT JOIN users u ON kb.created_by = u.id
        ORDER BY kb.created_at DESC
      `);
      res.json(rows);
    } catch (err) {
      console.error('Error fetching knowledge base articles:', err);
      res.status(500).json({ error: 'Failed to fetch articles' });
    }
  });

  // GET /api/knowledge-base/:id
  router.get('/:id', requireAuth(), async (req, res) => {
    const { id } = req.params;

    try {
      const { rows } = await pool.query(`
        SELECT
          kb.id, kb.title, kb.slug, kb.description, kb.category,
          kb.file_name, kb.file_type, kb.file_size, kb.created_at, kb.updated_at,
          u.username as created_by_username
        FROM knowledge_base kb
        LEFT JOIN users u ON kb.created_by = u.id
        WHERE kb.id = $1
      `, [id]);

      if (!rows[0]) {
        return res.status(404).json({ error: 'Article not found' });
      }

      res.json(rows[0]);
    } catch (err) {
      console.error('Error fetching article:', err);
      res.status(500).json({ error: 'Failed to fetch article' });
    }
  });

  // GET /api/knowledge-base/:id/content
  router.get('/:id/content', requireAuth(), async (req, res) => {
    const { id } = req.params;

    try {
      const { rows } = await pool.query(
        'SELECT file_path, file_name, file_type FROM knowledge_base WHERE id = $1', [id]
      );
      const row = rows[0];

      if (!row) {
        return res.status(404).json({ error: 'Document not found' });
      }

      if (!fs.existsSync(row.file_path)) {
        return res.status(404).json({ error: 'File not found on disk' });
      }

      logAudit({
        userId: req.user.id,
        username: req.user.username,
        action: 'VIEW_KB_ARTICLE',
        entityType: 'knowledge_base',
        entityId: String(id),
        details: { filename: row.file_name },
        ipAddress: req.ip
      });

      let contentType = row.file_type || 'application/octet-stream';
      if (row.file_name.endsWith('.md')) {
        contentType = 'text/plain; charset=utf-8';
      } else if (row.file_name.endsWith('.txt')) {
        contentType = 'text/plain; charset=utf-8';
      }

      const safeFileName = row.file_name.replace(/["\r\n\\]/g, '');
      res.setHeader('Content-Type', contentType);
      res.setHeader('Content-Disposition', `inline; filename="${safeFileName}"`);
      res.removeHeader('X-Frame-Options');
      const corsOrigins = process.env.CORS_ORIGINS ? process.env.CORS_ORIGINS.split(',').join(' ') : 'http://localhost:3000';
      res.setHeader('Content-Security-Policy', `frame-ancestors 'self' ${corsOrigins}`);
      res.sendFile(row.file_path);
    } catch (err) {
      console.error('Error fetching document:', err);
      res.status(500).json({ error: 'Failed to fetch document' });
    }
  });

  // GET /api/knowledge-base/:id/download
  router.get('/:id/download', requireAuth(), async (req, res) => {
    const { id } = req.params;

    try {
      const { rows } = await pool.query(
        'SELECT file_path, file_name, file_type FROM knowledge_base WHERE id = $1', [id]
      );
      const row = rows[0];

      if (!row) {
        return res.status(404).json({ error: 'Document not found' });
      }

      if (!fs.existsSync(row.file_path)) {
        return res.status(404).json({ error: 'File not found on disk' });
      }

      logAudit({
        userId: req.user.id,
        username: req.user.username,
        action: 'DOWNLOAD_KB_ARTICLE',
        entityType: 'knowledge_base',
        entityId: String(id),
        details: { filename: row.file_name },
        ipAddress: req.ip
      });

      const safeDownloadName = row.file_name.replace(/["\r\n\\]/g, '');
      res.setHeader('Content-Type', row.file_type || 'application/octet-stream');
      res.setHeader('Content-Disposition', `attachment; filename="${safeDownloadName}"`);
      res.sendFile(row.file_path);
    } catch (err) {
      console.error('Error fetching document:', err);
      res.status(500).json({ error: 'Failed to fetch document' });
    }
  });

  // DELETE /api/knowledge-base/:id
  router.delete('/:id', requireAuth(), requireGroup('Admin', 'Standard_User'), async (req, res) => {
    const { id } = req.params;

    try {
      const { rows } = await pool.query(
        'SELECT file_path, title, created_by FROM knowledge_base WHERE id = $1', [id]
      );
      const row = rows[0];

      if (!row) {
        return res.status(404).json({ error: 'Article not found' });
      }

      // Ownership check: Standard_User can only delete articles they created
      if (req.user.group === 'Standard_User' && row.created_by !== req.user.id) {
        return res.status(403).json({ error: 'You can only delete resources you created' });
      }

      await pool.query('DELETE FROM knowledge_base WHERE id = $1', [id]);

      // Delete file
      if (fs.existsSync(row.file_path)) {
        fs.unlinkSync(row.file_path);
      }

      logAudit({
        userId: req.user.id,
        username: req.user.username,
        action: 'DELETE_KB_ARTICLE',
        entityType: 'knowledge_base',
        entityId: String(id),
        details: { title: row.title },
        ipAddress: req.ip
      });

      res.json({ success: true });
    } catch (err) {
      console.error('Error deleting article:', err);
      res.status(500).json({ error: 'Failed to delete article' });
    }
  });

  return router;
}

module.exports = createKnowledgeBaseRouter;
