const express = require('express');
const router = express.Router();
const { getDb, logAudit } = require('../../db');
const emailService = require('../../email');

// ============ TIME ENTRIES ============

router.get('/time', (req, res) => {
  const db = getDb();
  const { client_id, date_from, date_to } = req.query;
  let sql = `
    SELECT t.*, c.name as client_name, e.title as engagement_title, u.username
    FROM time_entries t
    LEFT JOIN clients c ON c.id = t.client_id
    LEFT JOIN engagements e ON e.id = t.engagement_id
    LEFT JOIN users u ON u.id = t.user_id
    WHERE 1=1`;
  const params = [];
  if (client_id) { sql += ' AND t.client_id = ?'; params.push(client_id); }
  if (date_from) { sql += ' AND t.date >= ?'; params.push(date_from); }
  if (date_to) { sql += ' AND t.date <= ?'; params.push(date_to); }
  sql += ' ORDER BY t.date DESC, t.created_at DESC';
  const entries = db.prepare(sql).all(...params);
  res.json({
    entries,
    totalHours: entries.reduce((s, e) => s + e.hours, 0),
    billableHours: entries.filter(e => e.billable).reduce((s, e) => s + e.hours, 0)
  });
});

router.post('/time', (req, res) => {
  const db = getDb();
  const { client_id, engagement_id, date, hours, description, billable, hourly_rate } = req.body;
  if (!date || !hours) return res.status(400).json({ error: 'Datum en uren zijn verplicht' });
  const result = db.prepare('INSERT INTO time_entries (user_id, client_id, engagement_id, date, hours, description, billable, hourly_rate) VALUES (?,?,?,?,?,?,?,?)')
    .run(req.session.userId, client_id || null, engagement_id || null, date, parseFloat(hours), description || '', billable ? 1 : 0, parseFloat(hourly_rate) || 150.0);
  logAudit(req.session.userId, req.session.username, 'time_entry_created', 'time_entry', result.lastInsertRowid, `${hours}u geregistreerd op ${date} via SPA`);
  res.status(201).json({ id: result.lastInsertRowid });
});

router.put('/time/:id', (req, res) => {
  const db = getDb();
  const { client_id, engagement_id, date, hours, description, billable, hourly_rate } = req.body;
  db.prepare("UPDATE time_entries SET client_id=?, engagement_id=?, date=?, hours=?, description=?, billable=?, hourly_rate=?, updated_at=datetime('now') WHERE id=?")
    .run(client_id || null, engagement_id || null, date, parseFloat(hours), description || '', billable ? 1 : 0, parseFloat(hourly_rate) || 150.0, req.params.id);
  res.json({ ok: true });
});

router.delete('/time/:id', (req, res) => {
  const db = getDb();
  db.prepare('DELETE FROM time_entries WHERE id = ?').run(req.params.id);
  res.json({ ok: true });
});

// Factuur genereren uit billable uren
router.post('/time/create-invoice', (req, res) => {
  const db = getDb();
  const { client_id, date_from, date_to } = req.body;
  if (!client_id) return res.status(400).json({ error: 'Client is verplicht' });
  const entries = db.prepare(`
    SELECT t.*, e.title as engagement_title
    FROM time_entries t
    LEFT JOIN engagements e ON e.id = t.engagement_id
    WHERE t.client_id = ? AND t.billable = 1
    AND (? IS NULL OR t.date >= ?) AND (? IS NULL OR t.date <= ?)
  `).all(client_id, date_from || null, date_from || null, date_to || null, date_to || null);
  if (entries.length === 0) return res.status(400).json({ error: 'Geen facturabele uren gevonden' });
  const totalHours = entries.reduce((s, e) => s + e.hours, 0);
  const rate = entries[0].hourly_rate || 150;
  const subtotal = totalHours * rate;
  const tax = subtotal * 0.21;
  const count = db.prepare('SELECT COUNT(*) as cnt FROM invoices').get().cnt + 1;
  const number = `FACT-${new Date().getFullYear()}-${String(count).padStart(4, '0')}`;
  const date = new Date().toISOString().split('T')[0];
  const result = db.prepare('INSERT INTO invoices (client_id, number, status, date, due_date, subtotal, tax, total, notes) VALUES (?,?,?,?,?,?,?,?,?)')
    .run(client_id, number, 'draft', date, '', subtotal, tax, subtotal + tax, `Factuur gegenereerd uit ${entries.length} tijdregistraties`);
  const invoiceId = result.lastInsertRowid;
  const insert = db.prepare('INSERT INTO invoice_items (invoice_id, description, quantity, unit_price, total) VALUES (?,?,?,?,?)');
  entries.forEach(e => {
    const lineTotal = e.hours * (e.hourly_rate || rate);
    insert.run(invoiceId, `${e.date} - ${e.engagement_title || 'Werkzaamheden'}: ${e.description || ''}`, e.hours, e.hourly_rate || rate, lineTotal);
  });
  logAudit(req.session.userId, req.session.username, 'invoice_from_time', 'invoice', invoiceId, `Factuur ${number} gemaakt uit ${entries.length} uren via SPA`);
  res.status(201).json({ id: invoiceId, number });
});

// ============ INVOICES ============

router.get('/invoices', (req, res) => {
  const db = getDb();
  const invoices = db.prepare(`
    SELECT i.*, c.name as client_name
    FROM invoices i JOIN clients c ON c.id = i.client_id
    ORDER BY i.created_at DESC
  `).all();
  res.json({
    invoices,
    totalOutstanding: invoices.filter(i => i.status === 'sent' || i.status === 'overdue').reduce((s, i) => s + i.total, 0),
    totalPaid: invoices.filter(i => i.status === 'paid').reduce((s, i) => s + i.total, 0)
  });
});

router.post('/invoices', (req, res) => {
  const db = getDb();
  const { client_id, date, due_date, notes, items, subtotal, tax } = req.body;
  if (!client_id) return res.status(400).json({ error: 'Client is verplicht' });
  const count = db.prepare('SELECT COUNT(*) as cnt FROM invoices').get().cnt + 1;
  const number = `FACT-${new Date().getFullYear()}-${String(count).padStart(4, '0')}`;
  const sub = parseFloat(subtotal) || 0;
  const taxAmt = parseFloat(tax) || 0;
  const result = db.prepare('INSERT INTO invoices (client_id, number, status, date, due_date, subtotal, tax, total, notes) VALUES (?,?,?,?,?,?,?,?,?)')
    .run(client_id, number, 'draft', date || new Date().toISOString().split('T')[0], due_date || '', sub, taxAmt, sub + taxAmt, notes || '');
  const invoiceId = result.lastInsertRowid;
  if (items && Array.isArray(items)) {
    const insert = db.prepare('INSERT INTO invoice_items (invoice_id, description, quantity, unit_price, total) VALUES (?,?,?,?,?)');
    for (const item of items) {
      if (item.description) {
        const itemTotal = (parseFloat(item.quantity) || 1) * (parseFloat(item.unit_price) || 0);
        insert.run(invoiceId, item.description, parseFloat(item.quantity) || 1, parseFloat(item.unit_price) || 0, itemTotal);
      }
    }
  }
  logAudit(req.session.userId, req.session.username, 'invoice_created', 'invoice', invoiceId, `Factuur ${number} aangemaakt via SPA`);
  res.status(201).json({ id: invoiceId, number });
});

router.get('/invoices/:id', (req, res) => {
  const db = getDb();
  const invoice = db.prepare('SELECT i.*, c.name as client_name, c.contact_name, c.contact_email, c.contact_phone, c.website FROM invoices i JOIN clients c ON c.id = i.client_id WHERE i.id = ?').get(req.params.id);
  if (!invoice) return res.status(404).json({ error: 'Factuur niet gevonden' });
  const items = db.prepare('SELECT * FROM invoice_items WHERE invoice_id = ?').all(req.params.id);
  res.json({ invoice, items });
});

router.post('/invoices/:id/status', (req, res) => {
  const db = getDb();
  db.prepare("UPDATE invoices SET status=?, updated_at=datetime('now') WHERE id=?").run(req.body.status, req.params.id);
  res.json({ ok: true });
});

router.delete('/invoices/:id', (req, res) => {
  const db = getDb();
  db.prepare('DELETE FROM invoices WHERE id = ?').run(req.params.id);
  res.json({ ok: true });
});

router.post('/invoices/:id/send-email', async (req, res) => {
  const db = getDb();
  const invoice = db.prepare('SELECT i.*, c.name as client_name, c.contact_email FROM invoices i JOIN clients c ON c.id = i.client_id WHERE i.id = ?').get(req.params.id);
  if (!invoice) return res.status(404).json({ error: 'Factuur niet gevonden' });
  const account = db.prepare('SELECT * FROM email_accounts WHERE user_id = ? AND active = 1 LIMIT 1').get(req.session.userId);
  if (!account) return res.status(400).json({ error: 'Geen e-mailaccount geconfigureerd' });
  const items = db.prepare('SELECT * FROM invoice_items WHERE invoice_id = ?').all(req.params.id);
  let text = `Factuur ${invoice.number}\n\nClient: ${invoice.client_name}\nDatum: ${invoice.date}\nVervaldatum: ${invoice.due_date || '-'}\n\n`;
  items.forEach(item => { text += `${item.description}  x${item.quantity}  EUR ${(item.unit_price || 0).toFixed(2)}  EUR ${(item.total || 0).toFixed(2)}\n`; });
  text += `\nSubtotaal: EUR ${(invoice.subtotal || 0).toFixed(2)}\nBTW: EUR ${(invoice.tax || 0).toFixed(2)}\nTotaal: EUR ${(invoice.total || 0).toFixed(2)}\n\nMek-Tech Consulting`;
  const to = invoice.contact_email || account.email;
  try {
    await emailService.sendEmail(account.id, to, `Factuur ${invoice.number}`, text, text.replace(/\n/g, '<br>'));
    logAudit(req.session.userId, req.session.username, 'invoice_emailed', 'invoice', invoice.id, `Factuur ${invoice.number} gemaild naar ${to}`);
    db.prepare("UPDATE invoices SET status='sent', updated_at=datetime('now') WHERE id=?").run(req.params.id);
    res.json({ ok: true });
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});

// ============ FINANCE OVERZICHT ============

router.get('/finance', (req, res) => {
  const db = getDb();
  const year = parseInt(req.query.year) || new Date().getFullYear();
  const timeStats = db.prepare(`
    SELECT strftime('%m', date) as month, SUM(hours) as hours,
      SUM(CASE WHEN billable = 1 THEN hours ELSE 0 END) as billable_hours
    FROM time_entries WHERE strftime('%Y', date) = ?
    GROUP BY month ORDER BY month
  `).all(String(year));
  const invoiceStats = db.prepare(`
    SELECT strftime('%m', date) as month,
      SUM(CASE WHEN status = 'paid' THEN total ELSE 0 END) as paid,
      SUM(CASE WHEN status IN ('sent','overdue') THEN total ELSE 0 END) as outstanding
    FROM invoices WHERE strftime('%Y', date) = ?
    GROUP BY month ORDER BY month
  `).all(String(year));
  const totals = {
    hoursThisYear: db.prepare("SELECT COALESCE(SUM(hours),0) as s FROM time_entries WHERE strftime('%Y', date) = ?").get(String(year)).s,
    paidThisYear: db.prepare("SELECT COALESCE(SUM(total),0) as s FROM invoices WHERE status='paid' AND strftime('%Y', date) = ?").get(String(year)).s,
    outstanding: db.prepare("SELECT COALESCE(SUM(total),0) as s FROM invoices WHERE status IN ('sent','overdue')").get().s,
    draftTotal: db.prepare("SELECT COALESCE(SUM(total),0) as s FROM invoices WHERE status='draft'").get().s
  };
  res.json({ year, timeStats, invoiceStats, totals });
});

module.exports = router;
