// simple Node/Express backend for admin login/example
const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
const sqlite3 = require('sqlite3').verbose();
const cors = require('cors');

const app = express();
const db = new sqlite3.Database('./backend/db.sqlite');
const SECRET = process.env.JWT_SECRET || 'changeme';

app.use(cors());
app.use(express.json());

// initialize tables and default admin
db.serialize(() => {
  db.run(`CREATE TABLE IF NOT EXISTS admins (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    username TEXT UNIQUE,
    password_hash TEXT
  )`);

  db.get('SELECT COUNT(*) as count FROM admins', (err, row) => {
    if (err) throw err;
    if (row.count === 0) {
      const pw = 'admin123'; // change immediately in production
      bcrypt.hash(pw, 10, (err, hash) => {
        if (err) throw err;
        db.run('INSERT INTO admins (username, password_hash) VALUES (?, ?)', ['admin', hash]);
        console.log('created default admin user -> admin/' + pw);
      });
    }
  });
});

function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  if (!authHeader) return res.sendStatus(401);
  const token = authHeader.split(' ')[1];
  if (!token) return res.sendStatus(401);

  jwt.verify(token, SECRET, (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
}

function requireAdmin(req, res, next) {
  if (!req.user || req.user.role !== 'admin') return res.sendStatus(403);
  next();
}

app.post('/api/login', (req, res) => {
  const { username, password } = req.body;
  if (!username || !password) return res.status(400).json({ error: 'Missing credentials' });

  db.get('SELECT * FROM admins WHERE username = ?', username, (err, row) => {
    if (err) return res.status(500).json({ error: 'DB error' });
    if (!row) return res.status(401).json({ error: 'Invalid username or password' });

    bcrypt.compare(password, row.password_hash, (err, result) => {
      if (err) return res.status(500).json({ error: 'Error checking password' });
      if (!result) return res.status(401).json({ error: 'Invalid username or password' });

      const user = { id: row.id, username: row.username, role: 'admin' };
      const token = jwt.sign(user, SECRET, { expiresIn: '1h' });
      res.json({ token, user });
    });
  });
});

app.get('/api/admin/data', authenticateToken, requireAdmin, (req, res) => {
  res.json({ message: 'You are viewing protected data', user: req.user });
});

// sample CRUD for "items" table to demonstrate connect/edit
db.serialize(() => {
  db.run(`CREATE TABLE IF NOT EXISTS items (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    title TEXT,
    content TEXT
  )`);
});

app.get('/api/admin/items', authenticateToken, requireAdmin, (req, res) => {
  db.all('SELECT * FROM items', (err, rows) => {
    if (err) return res.status(500).json({ error: 'DB error' });
    res.json(rows);
  });
});

app.post('/api/admin/items', authenticateToken, requireAdmin, (req, res) => {
  const { title, content } = req.body;
  db.run('INSERT INTO items (title, content) VALUES (?, ?)', [title, content], function (err) {
    if (err) return res.status(500).json({ error: 'DB error' });
    res.json({ id: this.lastID, title, content });
  });
});

app.put('/api/admin/items/:id', authenticateToken, requireAdmin, (req, res) => {
  const { id } = req.params;
  const { title, content } = req.body;
  db.run('UPDATE items SET title = ?, content = ? WHERE id = ?', [title, content, id], function (err) {
    if (err) return res.status(500).json({ error: 'DB error' });
    res.json({ changed: this.changes });
  });
});

app.delete('/api/admin/items/:id', authenticateToken, requireAdmin, (req, res) => {
  const { id } = req.params;
  db.run('DELETE FROM items WHERE id = ?', id, function (err) {
    if (err) return res.status(500).json({ error: 'DB error' });
    res.json({ deleted: this.changes });
  });
});

const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Backend listening on http://localhost:${port}`));
