// API Communication and State Sync const API = { tokenKey: 'el_puro_jwt_token', userKey: 'el_puro_username', getToken() { return localStorage.getItem(this.tokenKey); }, getUsername() { return localStorage.getItem(this.userKey); }, setAuth(token, username) { localStorage.setItem(this.tokenKey, token); localStorage.setItem(this.userKey, username); }, logout() { localStorage.removeItem(this.tokenKey); localStorage.removeItem(this.userKey); }, async register(username, password, websiteHp = '') { const res = await fetch('/api/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password, website_hp: websiteHp }) }); if (!res.ok) { const err = await res.json().catch(() => ({ detail: 'Registration failed' })); throw new Error(err.detail || 'Registration failed'); } const data = await res.json(); this.setAuth(data.token, data.username); return data; }, async login(username, password) { const res = await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) }); if (!res.ok) { const err = await res.json().catch(() => ({ detail: 'Invalid credentials' })); throw new Error(err.detail || 'Login failed'); } const data = await res.json(); this.setAuth(data.token, data.username); return data; }, async loadRemoteSave() { const token = this.getToken(); if (!token) return null; try { const res = await fetch('/api/game/state', { headers: { 'Authorization': `Bearer ${token}` } }); if (!res.ok) { if (res.status === 401) this.logout(); return null; } const data = await res.json(); return data.has_save ? data.save_data : null; } catch (e) { console.warn('Network issue loading cloud save, fallback to local', e); return null; } }, async syncTick(actions = []) { const token = this.getToken(); if (!token) return null; try { const res = await fetch('/api/game/tick', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ actions }) }); if (!res.ok) { if (res.status === 401) this.logout(); return null; } const data = await res.json(); return data.save_data; } catch (e) { console.warn('Network tick failed, queuing actions', e); return null; } }, async saveRemote(saveData) { const token = this.getToken(); if (!token) return; try { await fetch('/api/game/save', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ save_data: saveData }) }); } catch (e) { console.warn('Failed cloud save sync', e); } } };