const express = require('express');
const Database = require('better-sqlite3');
const path = require('path');
const crypto = require('crypto');

const app = express();
const PORT = process.env.PORT || 3000;
const DB_PATH = process.env.DB_PATH || '/data/revfulop.db';

// Simple auth config (set SIMPLE_AUTH_PASSWORD env var to enable)
const AUTH_PASSWORD = process.env.SIMPLE_AUTH_PASSWORD || '';
const AUTH_ENABLED = AUTH_PASSWORD.length > 0;

// UI config (all overridable via env vars, no rebuild needed)
const UI_CONFIG = {
  fontSize: process.env.UI_FONT_SIZE || '15',           // base font size in px
  titleSize: process.env.UI_TITLE_SIZE || '32',         // main title size in px
  calendarSize: process.env.UI_CALENDAR_SIZE || '14',   // calendar day number size in px
  buttonSize: process.env.UI_BUTTON_SIZE || '14',       // button/input font size in px
  siteName: process.env.UI_SITE_NAME || 'Nyaraló Naptár',
  siteSubtitle: process.env.UI_SITE_SUBTITLE || 'Révfülöp · Balaton',
  loginTagline: process.env.UI_LOGIN_TAGLINE || 'Ahol a család találkozik,<br>ahol a nyár kezdődik.',
  loginSubtitle: process.env.UI_LOGIN_SUBTITLE || 'A révfülöpi nyaraló foglalási naptára',
};

// Family members config (can be overridable via FAMILY_MEMBERS env var as JSON)
const DEFAULT_MEMBERS = [
  { id: "katinka", name: "Katinka", color: "#513eff" },
  { id: "orsi", name: "Orsi", color: "#a15dd8" },
  { id: "lili", name: "Lili", color: "#ffe70c" },
  { id: "bazsi", name: "Bazsi", color: "#2db84a" },
];

let FAMILY_MEMBERS;
try {
  FAMILY_MEMBERS = process.env.FAMILY_MEMBERS ? JSON.parse(process.env.FAMILY_MEMBERS) : DEFAULT_MEMBERS;
} catch {
  FAMILY_MEMBERS = DEFAULT_MEMBERS;
}

// Init DB
const db = new Database(DB_PATH);
db.pragma('journal_mode = WAL');
db.exec(`
  CREATE TABLE IF NOT EXISTS bookings (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    member_id TEXT NOT NULL,
    start_date TEXT NOT NULL,
    end_date TEXT NOT NULL,
    status TEXT NOT NULL DEFAULT 'planned',
    created_at TEXT DEFAULT (datetime('now'))
  );
  CREATE TABLE IF NOT EXISTS comments (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    member_id TEXT NOT NULL,
    text TEXT NOT NULL,
    created_at TEXT DEFAULT (datetime('now'))
  );
`);

app.use(express.json());

// Session tokens: token -> { created, memberId }
const sessions = new Map();

// Auth helper: get logged-in member from token
function getMember(req) {
  const token = req.headers['x-auth-token'];
  if (!token) return null;
  const session = sessions.get(token);
  if (!session) return null;
  return session.memberId;
}

// Auth middleware
function authMiddleware(req, res, next) {
  if (!AUTH_ENABLED) return next();

  // Skip auth for login, auth-status, members, config, and public endpoints
  if (req.path === '/api/login' || req.path === '/api/auth-status' || req.path === '/api/members' || req.path === '/api/config' || req.path === '/api/public/bookings' || req.path === '/public') return next();

  const token = req.headers['x-auth-token'];
  if (token && sessions.has(token)) {
    return next();
  }

  if (req.path.startsWith('/api/')) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  next();
}

app.use(authMiddleware);

// Auth endpoints
app.get('/api/auth-status', (req, res) => {
  res.json({ authEnabled: AUTH_ENABLED });
});

app.post('/api/login', (req, res) => {
  if (!AUTH_ENABLED) return res.json({ success: true, token: 'none', memberId: null });

  const { password, memberId } = req.body;

  // Validate member exists
  if (!memberId || !FAMILY_MEMBERS.find(m => m.id === memberId)) {
    return res.status(400).json({ success: false, error: 'Válassz egy családtagot' });
  }

  if (password === AUTH_PASSWORD) {
    const token = crypto.randomBytes(32).toString('hex');
    sessions.set(token, { created: Date.now(), memberId });
    // Clean old sessions (>7 days)
    for (const [t, s] of sessions) {
      if (Date.now() - s.created > 7 * 86400000) sessions.delete(t);
    }
    res.json({ success: true, token, memberId });
  } else {
    res.status(401).json({ success: false, error: 'Hibás jelszó' });
  }
});

// Who am I endpoint
app.get('/api/me', (req, res) => {
  const memberId = getMember(req);
  if (!memberId) return res.json({ memberId: null });
  const member = FAMILY_MEMBERS.find(m => m.id === memberId);
  res.json({ memberId, member });
});

// Members endpoint
app.get('/api/members', (req, res) => {
  res.json(FAMILY_MEMBERS);
});

// UI config endpoint
app.get('/api/config', (req, res) => {
  res.json(UI_CONFIG);
});

// Bookings CRUD
app.get('/api/bookings', (req, res) => {
  const bookings = db.prepare('SELECT * FROM bookings ORDER BY start_date').all();
  res.json(bookings);
});

app.post('/api/bookings', (req, res) => {
  const { start_date, end_date, status } = req.body;
  // Use logged-in member if auth enabled, otherwise accept from body
  const member_id = AUTH_ENABLED ? getMember(req) : req.body.member_id;
  if (!member_id || !start_date || !end_date) {
    return res.status(400).json({ error: 'Missing fields' });
  }
  const result = db.prepare(
    'INSERT INTO bookings (member_id, start_date, end_date, status) VALUES (?, ?, ?, ?)'
  ).run(member_id, start_date, end_date, status || 'planned');
  res.json({ id: result.lastInsertRowid });
});

app.put('/api/bookings/:id', (req, res) => {
  const { status } = req.body;
  db.prepare('UPDATE bookings SET status = ? WHERE id = ?').run(status, req.params.id);
  res.json({ success: true });
});

app.delete('/api/bookings/:id', (req, res) => {
  db.prepare('DELETE FROM bookings WHERE id = ?').run(req.params.id);
  res.json({ success: true });
});

// Comments CRUD
app.get('/api/comments', (req, res) => {
  const comments = db.prepare('SELECT * FROM comments ORDER BY created_at DESC').all();
  res.json(comments);
});

app.post('/api/comments', (req, res) => {
  const { text } = req.body;
  const member_id = AUTH_ENABLED ? getMember(req) : req.body.member_id;
  if (!member_id || !text) {
    return res.status(400).json({ error: 'Missing fields' });
  }
  const result = db.prepare(
    'INSERT INTO comments (member_id, text) VALUES (?, ?)'
  ).run(member_id, text);
  res.json({ id: result.lastInsertRowid });
});

app.delete('/api/comments/:id', (req, res) => {
  const memberId = AUTH_ENABLED ? getMember(req) : req.body.member_id;
  const comment = db.prepare('SELECT * FROM comments WHERE id = ?').get(req.params.id);
  if (!comment) return res.status(404).json({ error: 'Not found' });
  if (AUTH_ENABLED && comment.member_id !== memberId) {
    return res.status(403).json({ error: 'Csak a saját hozzászólásod törölheted' });
  }
  db.prepare('DELETE FROM comments WHERE id = ?').run(req.params.id);
  res.json({ success: true });
});

// Public bookings endpoint - returns only dates, no member info
app.get('/api/public/bookings', (req, res) => {
  const bookings = db.prepare('SELECT start_date, end_date FROM bookings ORDER BY start_date').all();
  res.json(bookings);
});

// Public calendar page (no auth)
app.get('/public', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'public.html'));
});

// Serve static frontend
app.use(express.static(path.join(__dirname, 'public')));
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

app.listen(PORT, '0.0.0.0', () => {
  console.log(`Révfülöp Calendar running on port ${PORT}`);
  console.log(`Auth: ${AUTH_ENABLED ? 'ENABLED (simple password)' : 'DISABLED (public access)'}`);
  console.log(`Members: ${FAMILY_MEMBERS.map(m => m.name).join(', ')}`);
  console.log(`UI: font=${UI_CONFIG.fontSize}px, title=${UI_CONFIG.titleSize}px, calendar=${UI_CONFIG.calendarSize}px`);
});