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

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

const BORROW_DAYS = 14;
const FINE_PER_DAY = 1.0;

router.get('/', async (req, res) => {
  try {
    const { status } = req.query;
    let sql = `
      SELECT b.*, bk.title AS book_title, bk.isbn, m.name AS member_name, m.email AS member_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 (status) {
      sql += ' AND b.status = ?';
      params.push(status);
    }
    sql += ' ORDER BY b.borrow_date DESC';

    const [rows] = await pool.query(sql, params);
    res.json(rows);
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Failed to fetch borrowings.' });
  }
});

router.post('/', async (req, res) => {
  const conn = await pool.getConnection();
  try {
    const { book_id, member_id, due_date } = req.body;
    if (!book_id || !member_id) {
      return res.status(400).json({ message: 'Book and member are required.' });
    }

    await conn.beginTransaction();

    const [books] = await conn.query('SELECT * FROM books WHERE id = ? FOR UPDATE', [book_id]);
    if (books.length === 0) {
      await conn.rollback();
      return res.status(404).json({ message: 'Book not found.' });
    }
    if (books[0].available < 1) {
      await conn.rollback();
      return res.status(400).json({ message: 'No copies available.' });
    }

    const [members] = await conn.query(
      "SELECT * FROM members WHERE id = ? AND status = 'active'",
      [member_id]
    );
    if (members.length === 0) {
      await conn.rollback();
      return res.status(400).json({ message: 'Member not found or inactive.' });
    }

    const due = due_date || new Date(Date.now() + BORROW_DAYS * 86400000).toISOString().split('T')[0];
    const [result] = await conn.query(
      "INSERT INTO borrowings (book_id, member_id, due_date, status) VALUES (?, ?, ?, 'borrowed')",
      [book_id, member_id, due]
    );
    await conn.query('UPDATE books SET available = available - 1 WHERE id = ?', [book_id]);

    await conn.commit();

    const [rows] = await pool.query(
      `SELECT b.*, bk.title AS book_title, m.name AS member_name
       FROM borrowings b
       JOIN books bk ON b.book_id = bk.id
       JOIN members m ON b.member_id = m.id
       WHERE b.id = ?`,
      [result.insertId]
    );
    res.status(201).json(rows[0]);
  } catch (err) {
    await conn.rollback();
    console.error(err);
    res.status(500).json({ message: 'Failed to issue book.' });
  } finally {
    conn.release();
  }
});

router.put('/:id/return', async (req, res) => {
  const conn = await pool.getConnection();
  try {
    await conn.beginTransaction();

    const [rows] = await conn.query(
      "SELECT * FROM borrowings WHERE id = ? AND status = 'borrowed' FOR UPDATE",
      [req.params.id]
    );
    if (rows.length === 0) {
      await conn.rollback();
      return res.status(404).json({ message: 'Active borrowing not found.' });
    }

    const borrowing = rows[0];
    const returnDate = new Date().toISOString().split('T')[0];
    let fine = 0;
    if (returnDate > borrowing.due_date) {
      const daysLate = Math.ceil(
        (new Date(returnDate) - new Date(borrowing.due_date)) / 86400000
      );
      fine = daysLate * FINE_PER_DAY;
    }

    await conn.query(
      "UPDATE borrowings SET return_date = ?, status = 'returned', fine = ? WHERE id = ?",
      [returnDate, fine, req.params.id]
    );
    await conn.query('UPDATE books SET available = available + 1 WHERE id = ?', [borrowing.book_id]);

    await conn.commit();

    const [updated] = await pool.query(
      `SELECT b.*, bk.title AS book_title, m.name AS member_name
       FROM borrowings b
       JOIN books bk ON b.book_id = bk.id
       JOIN members m ON b.member_id = m.id
       WHERE b.id = ?`,
      [req.params.id]
    );
    res.json(updated[0]);
  } catch (err) {
    await conn.rollback();
    console.error(err);
    res.status(500).json({ message: 'Failed to return book.' });
  } finally {
    conn.release();
  }
});

router.delete('/:id', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM borrowings WHERE id = ?', [req.params.id]);
    if (rows.length === 0) return res.status(404).json({ message: 'Borrowing not found.' });
    if (rows[0].status === 'borrowed') {
      await pool.query('UPDATE books SET available = available + 1 WHERE id = ?', [rows[0].book_id]);
    }
    await pool.query('DELETE FROM borrowings WHERE id = ?', [req.params.id]);
    res.json({ message: 'Borrowing record deleted.' });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Failed to delete borrowing.' });
  }
});

module.exports = router;
