const express = require("express"); const router = require("express").Router(); const db = require("../database/database"); const auth = require("../middleware/auth"); /* ───────────────────────────────────────── HELPER: Timer sicherstellen Legt beim allerersten Aufruf einen Eintrag an – laeuft dann fuer immer durch. Wird NUR durch collect() zurueckgesetzt. ───────────────────────────────────────── */ async function ensureTimer(userBuildingId) { const [[existing]] = await db.query( "SELECT last_collected FROM building_collect_timer WHERE user_building_id = ?", [userBuildingId], ); if (!existing) { await db.query( "INSERT INTO building_collect_timer (user_building_id, last_collected) VALUES (?, NOW())", [userBuildingId], ); } } /* ───────────────────────────────────────── HELPER: Produktionsdaten laden Gibt immer last_collected aus der DB ───────────────────────────────────────── */ async function loadMineData(userId, buildingId) { const [rows] = await db.query( ` SELECT ub.id AS user_building_id, ub.level, bp.resource, bp.amount, bp.cycle_seconds, bct.last_collected FROM user_buildings ub JOIN building_production bp ON bp.building_id = ub.building_id AND bp.level = ub.level JOIN building_collect_timer bct ON bct.user_building_id = ub.id WHERE ub.user_id = ? AND ub.building_id = ? `, [userId, buildingId], ); return rows; } /* ───────────────────────────────────────── GET /api/mine/:buildingId/status ───────────────────────────────────────── */ router.get("/:buildingId/status", auth, async (req, res) => { const userId = req.session.user.id; const buildingId = req.params.buildingId; try { // user_building holen const [[userBuilding]] = await db.query( "SELECT id, level FROM user_buildings WHERE user_id = ? AND building_id = ?", [userId, buildingId], ); if (!userBuilding) { return res.status(404).json({ error: "Gebaeude nicht gefunden" }); } // Timer einmalig starten falls noch nie geoeffnet await ensureTimer(userBuilding.id); const rows = await loadMineData(userId, buildingId); if (!rows.length) { return res.status(404).json({ error: "Gebaeude nicht gefunden" }); } const { cycle_seconds, last_collected, level } = rows[0]; const elapsed = Math.floor( (Date.now() - new Date(last_collected).getTime()) / 1000, ); const cycles = Math.floor(elapsed / cycle_seconds); const nextIn = cycle_seconds - (elapsed % cycle_seconds); const available = rows.map((r) => ({ resource: r.resource, amount: r.amount * cycles, })); const production = rows.map((r) => ({ resource: r.resource, amount: r.amount, })); res.json({ level, cycles, ready: cycles > 0, available, production, last_collected, next_cycle_in_seconds: nextIn, cycle_seconds, }); } catch (err) { console.error(err); res.status(500).json({ error: "DB Fehler" }); } }); /* ───────────────────────────────────────── POST /api/mine/:buildingId/collect Ressourcen gutschreiben + Timer reset ───────────────────────────────────────── */ router.post("/:buildingId/collect", auth, async (req, res) => { const userId = req.session.user.id; const buildingId = req.params.buildingId; try { // user_building holen const [[userBuilding]] = await db.query( "SELECT id FROM user_buildings WHERE user_id = ? AND building_id = ?", [userId, buildingId], ); if (!userBuilding) { return res.status(404).json({ error: "Gebaeude nicht gefunden" }); } // Timer sicherstellen (Fallback falls Status nie aufgerufen wurde) await ensureTimer(userBuilding.id); const rows = await loadMineData(userId, buildingId); if (!rows.length) { return res.status(404).json({ error: "Gebaeude nicht gefunden" }); } const { user_building_id, cycle_seconds, last_collected } = rows[0]; const elapsed = Math.floor( (Date.now() - new Date(last_collected).getTime()) / 1000, ); const cycles = Math.floor(elapsed / cycle_seconds); if (cycles < 1) { const waitSeconds = cycle_seconds - elapsed; const minutes = Math.floor(waitSeconds / 60); const seconds = waitSeconds % 60; return res.json({ error: "Noch nichts bereit", ready_in_seconds: waitSeconds, ready_in_display: `${minutes}m ${seconds}s`, }); } // Jede Ressource einzeln gutschreiben const allowedResources = [ "gold", "silver", "copper", "iron", "wood", "stone", "gems", ]; for (const row of rows) { if (!allowedResources.includes(row.resource)) continue; const toAdd = row.amount * cycles; await db.query( `UPDATE account_currency SET \`${row.resource}\` = \`${row.resource}\` + ? WHERE account_id = ?`, [toAdd, userId], ); } // Timer zuruecksetzen: last_collected um genau die abgeschlossenen // Zyklen vorruecken – Restsekunden bleiben erhalten, kein Verlust const newLastCollected = new Date( new Date(last_collected).getTime() + cycles * cycle_seconds * 1000, ); await db.query( "UPDATE building_collect_timer SET last_collected = ? WHERE user_building_id = ?", [newLastCollected, user_building_id], ); const collected = rows.map((r) => ({ resource: r.resource, amount: r.amount * cycles, })); res.json({ success: true, cycles, collected }); } catch (err) { console.error(err); res.status(500).json({ error: "DB Fehler" }); } }); module.exports = router;