const express = require('express');
const PDFDocument = require('pdfkit');
const pool = require('../config/db');
const auth = require('../middleware/auth');

const router = express.Router();
router.use(auth);

router.get('/dashboard', async (req, res) => {
  try {
    const [[books]] = await pool.query(
      'SELECT COUNT(*) AS total, SUM(quantity) AS copies, SUM(available) AS available FROM books'
    );
    const [[members]] = await pool.query(
      "SELECT COUNT(*) AS total, SUM(status = 'active') AS active FROM members"
    );
    const [[borrowings]] = await pool.query(`
      SELECT
        COUNT(*) AS total,
        SUM(status = 'borrowed') AS active,
        SUM(status = 'returned') AS returned,
        SUM(status = 'borrowed' AND due_date < CURDATE()) AS overdue
      FROM borrowings
    `);
    const [recentBorrowings] = await pool.query(`
      SELECT b.id, bk.title, m.name AS member_name, b.borrow_date, b.due_date, b.status
      FROM borrowings b
      JOIN books bk ON b.book_id = bk.id
      JOIN members m ON b.member_id = m.id
      ORDER BY b.created_at DESC LIMIT 5
    `);
    const [popularBooks] = await pool.query(`
      SELECT bk.title, bk.author, COUNT(br.id) AS borrow_count
      FROM books bk
      LEFT JOIN borrowings br ON bk.id = br.book_id
      GROUP BY bk.id
      ORDER BY borrow_count DESC
      LIMIT 5
    `);

    res.json({
      books: { total: books.total, copies: books.copies || 0, available: books.available || 0 },
      members: { total: members.total, active: Number(members.active) || 0 },
      borrowings: {
        total: borrowings.total,
        active: Number(borrowings.active) || 0,
        returned: Number(borrowings.returned) || 0,
        overdue: Number(borrowings.overdue) || 0,
      },
      recentBorrowings,
      popularBooks,
    });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Failed to load dashboard stats.' });
  }
});

router.get('/inventory', async (req, res) => {
  try {
    const [books] = await pool.query('SELECT * FROM books ORDER BY category, title');
    res.json({ generatedAt: new Date().toISOString(), books });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Failed to generate inventory report.' });
  }
});

router.get('/borrowings', async (req, res) => {
  try {
    const { from, to, status } = req.query;
    let sql = `
      SELECT b.*, bk.title AS book_title, bk.isbn, m.name AS member_name, m.email
      FROM borrowings b
      JOIN books bk ON b.book_id = bk.id
      JOIN members m ON b.member_id = m.id
      WHERE 1=1
    `;
    const params = [];
    if (from) { sql += ' AND b.borrow_date >= ?'; params.push(from); }
    if (to) { sql += ' AND b.borrow_date <= ?'; params.push(to); }
    if (status) { sql += ' AND b.status = ?'; params.push(status); }

    sql += ' ORDER BY b.borrow_date DESC';
    const [rows] = await pool.query(sql, params);
    res.json({ generatedAt: new Date().toISOString(), borrowings: rows });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Failed to generate borrowings report.' });
  }
});

router.get('/overdue', async (req, res) => {
  try {
    const [rows] = await pool.query(`
      SELECT b.*, bk.title AS book_title, m.name AS member_name, m.email, m.phone,
             DATEDIFF(CURDATE(), b.due_date) AS days_overdue
      FROM borrowings b
      JOIN books bk ON b.book_id = bk.id
      JOIN members m ON b.member_id = m.id
      WHERE b.status = 'borrowed' AND b.due_date < CURDATE()
      ORDER BY b.due_date ASC
    `);
    res.json({ generatedAt: new Date().toISOString(), overdue: rows });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Failed to generate overdue report.' });
  }
});

router.get('/members', async (req, res) => {
  try {
    const [members] = await pool.query(`
      SELECT m.*,
        (SELECT COUNT(*) FROM borrowings b WHERE b.member_id = m.id) AS total_borrowings,
        (SELECT COUNT(*) FROM borrowings b WHERE b.member_id = m.id AND b.status = 'borrowed') AS active_borrowings
      FROM members m ORDER BY m.name
    `);
    res.json({ generatedAt: new Date().toISOString(), members });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Failed to generate members report.' });
  }
});

function sendPdf(res, title, rows, columns) {
  res.setHeader('Content-Type', 'application/pdf');
  res.setHeader('Content-Disposition', `attachment; filename="${title.replace(/\s+/g, '_')}.pdf"`);

  const doc = new PDFDocument({ margin: 50 });
  doc.pipe(res);

  doc.fontSize(20).text('Library Management System', { align: 'center' });
  doc.fontSize(14).text(title, { align: 'center' });
  doc.moveDown();
  doc.fontSize(10).text(`Generated: ${new Date().toLocaleString()}`, { align: 'right' });
  doc.moveDown();

  if (rows.length === 0) {
    doc.text('No records found.');
  } else {
    const colWidth = (doc.page.width - 100) / columns.length;
    let y = doc.y;
    doc.font('Helvetica-Bold');
    columns.forEach((col, i) => doc.text(col.label, 50 + i * colWidth, y, { width: colWidth, continued: false }));
    y += 20;
    doc.font('Helvetica');
    rows.forEach((row) => {
      if (y > doc.page.height - 80) {
        doc.addPage();
        y = 50;
      }
      columns.forEach((col, i) => {
        const val = row[col.key] != null ? String(row[col.key]) : '-';
        doc.text(val.substring(0, 30), 50 + i * colWidth, y, { width: colWidth });
      });
      y += 18;
    });
  }

  doc.end();
}

router.get('/pdf/inventory', async (req, res) => {
  try {
    const [books] = await pool.query('SELECT title, author, isbn, category, quantity, available FROM books ORDER BY title');
    sendPdf(res, 'Book Inventory Report', books, [
      { key: 'title', label: 'Title' },
      { key: 'author', label: 'Author' },
      { key: 'isbn', label: 'ISBN' },
      { key: 'available', label: 'Avail' },
    ]);
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Failed to generate PDF.' });
  }
});

router.get('/pdf/borrowings', async (req, res) => {
  try {
    const [rows] = await pool.query(`
      SELECT bk.title AS book_title, m.name AS member_name, b.borrow_date, b.due_date, b.status
      FROM borrowings b
      JOIN books bk ON b.book_id = bk.id
      JOIN members m ON b.member_id = m.id
      ORDER BY b.borrow_date DESC LIMIT 100
    `);
    sendPdf(res, 'Borrowings Report', rows, [
      { key: 'book_title', label: 'Book' },
      { key: 'member_name', label: 'Member' },
      { key: 'borrow_date', label: 'Borrowed' },
      { key: 'status', label: 'Status' },
    ]);
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Failed to generate PDF.' });
  }
});

router.get('/pdf/overdue', async (req, res) => {
  try {
    const [rows] = await pool.query(`
      SELECT bk.title AS book_title, m.name AS member_name, b.due_date,
             DATEDIFF(CURDATE(), b.due_date) AS days_overdue
      FROM borrowings b
      JOIN books bk ON b.book_id = bk.id
      JOIN members m ON b.member_id = m.id
      WHERE b.status = 'borrowed' AND b.due_date < CURDATE()
    `);
    sendPdf(res, 'Overdue Books Report', rows, [
      { key: 'book_title', label: 'Book' },
      { key: 'member_name', label: 'Member' },
      { key: 'due_date', label: 'Due Date' },
      { key: 'days_overdue', label: 'Days Late' },
    ]);
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Failed to generate PDF.' });
  }
});

module.exports = router;
