const express = require('express');
const mysql = require('mysql2/promise');
const cors = require('cors');
require('dotenv').config();

const app = express();
const port = process.env.PORT || 3001;

app.use(cors());
app.use(express.json({ limit: '50mb' }));

// Database connection pool
const pool = mysql.createPool({
  host: process.env.DB_HOST || 'localhost',
  user: process.env.DB_USER || 'root',
  password: process.env.DB_PASSWORD || '',
  database: process.env.DB_NAME || 'kemetrofest',
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
});

// Helper for snake_case to camelCase
const toCamelCase = (obj) => {
  const result = {};
  for (const key in obj) {
    const camelKey = key.replace(/(_\w)/g, m => m[1].toUpperCase());
    result[camelKey] = obj[key];
  }
  return result;
};

// Helper for camelCase to snake_case
const toSnakeCase = (obj) => {
  const result = {};
  for (const key in obj) {
    const snakeKey = key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
    result[snakeKey] = obj[key];
  }
  return result;
};

// Auth
app.post('/login', async (req, res) => {
  const { username, password } = req.body;
  try {
    const [rows] = await pool.query('SELECT * FROM admins WHERE username = ? AND password = ?', [username, password]);
    if (rows.length > 0) {
      // For simplicity, return a fake token. In real app, use JWT.
      const token = Math.random().toString(36).substring(2) + Date.now().toString(36);
      await pool.query('UPDATE admins SET last_login = NOW() WHERE id = ?', [rows[0].id]);
      res.json({ success: true, token, user: { username: rows[0].username } });
    } else {
      res.status(401).json({ error: 'Username atau password salah' });
    }
  } catch (error) {
    console.error('API Error (/login):', error);
    res.status(500).json({ error: error.message });
  }
});

// Routes
app.get('/settings', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM settings WHERE id = 1');
    res.json(rows[0] ? toCamelCase(rows[0]) : null);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.post('/settings', async (req, res) => {
  try {
    const data = toSnakeCase(req.body);
    delete data.updated_at;
    delete data.id;
    
    const keys = Object.keys(data);
    const values = Object.values(data);
    const setClause = keys.map(k => `${k} = ?`).join(', ');
    
    await pool.query(`UPDATE settings SET ${setClause} WHERE id = 1`, [...values]);
    res.json({ success: true });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.get('/slots', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM slots');
    res.json(rows.map(toCamelCase));
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.post('/slots', async (req, res) => {
  try {
    const slots = req.body;
    for (const slot of slots) {
      const data = toSnakeCase(slot);
      const keys = Object.keys(data);
      const values = Object.values(data);
      const placeholders = keys.map(() => '?').join(', ');
      const updateClause = keys.map(k => `${k} = VALUES(${k})`).join(', ');
      
      await pool.query(
        `INSERT INTO slots (${keys.join(', ')}) VALUES (${placeholders}) ON DUPLICATE KEY UPDATE ${updateClause}`,
        [...values]
      );
    }
    res.json({ success: true });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.get('/tenants', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM tenants ORDER BY submitted_at DESC');
    res.json(rows.map(toCamelCase));
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.post('/tenants', async (req, res) => {
  try {
    const data = toSnakeCase(req.body);
    const keys = Object.keys(data);
    const values = Object.values(data);
    const placeholders = keys.map(() => '?').join(', ');
    
    const [result] = await pool.query(`INSERT INTO tenants (${keys.join(', ')}) VALUES (${placeholders})`, values);
    res.json({ success: true, id: req.body.id });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.get('/partners', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM partners ORDER BY added_at DESC');
    res.json(rows.map(toCamelCase));
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.post('/partners', async (req, res) => {
  try {
    const data = toSnakeCase(req.body);
    const keys = Object.keys(data);
    const values = Object.values(data);
    const placeholders = keys.map(() => '?').join(', ');
    const updateClause = keys.map(k => `${k} = VALUES(${k})`).join(', ');

    await pool.query(
      `INSERT INTO partners (${keys.join(', ')}) VALUES (${placeholders}) ON DUPLICATE KEY UPDATE ${updateClause}`,
      [...values]
    );
    res.json({ success: true });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Global error handler
app.use((err, req, res, next) => {
  console.error('Unhandled Server Error:', err);
  res.status(500).json({ error: 'Terjadi kesalahan internal pada server' });
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});
