// api.jsx — client for the AgroSense Worker (/api/v3).
// The dashboard token (the Worker's READ_TOKEN) lives in localStorage and goes
// as "Authorization: Bearer"; photos take it as ?token= because <img> can't send headers.

const TOKEN_KEY = 'agrosense_token';

function getToken() {
  try { return localStorage.getItem(TOKEN_KEY) || ''; } catch { return ''; }
}

function setToken(t) {
  try {
    if (t) localStorage.setItem(TOKEN_KEY, t);
    else localStorage.removeItem(TOKEN_KEY);
  } catch { /* private mode */ }
}

class AuthError extends Error {}

async function call(path, options = {}) {
  const res = await fetch(path, {
    ...options,
    headers: { Authorization: `Bearer ${getToken()}`, 'Content-Type': 'application/json', ...(options.headers || {}) },
  });
  if (res.status === 401) throw new AuthError('token inválido');
  const json = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(json.error || `HTTP ${res.status}`);
  return json;
}

// Only what the dashboard draws (the full row has 43 columns)
const DASH_COLUMNS = [
  'ts', 'utc', 'time_src', 'firmware', 'temperature', 'humidity', 'pressure', 'sky_temperature',
  'ambient_temperature', 'cloud_cover', 'lux', 'wind_dir_deg', 'wind_speed_kmh', 'wind_gust_kmh',
  'rain_mm', 'interval_s', 'battery_voltage', 'battery_percent', 'charging', 'input_present',
  'sensors_ok', 'gps_fix', 'latitude', 'longitude', 'altitude_m', 'satellites', 'hdop',
  'rain_probability', 'rain_prediction', 'photo', 'prev_awake_ms', 'prev_wifi_rssi',
  'queue_backlog', 'boot_count', 'received_at',
].join(',');

async function fetchDevices() {
  return (await call('/api/v3/devices')).devices || [];
}

// Rows with ts >= fromTs, oldest first, following the pagination cursor.
async function fetchReadings(deviceId, fromTs) {
  let rows = [];
  let after = 0;
  for (let page = 0; page < 10; page++) {
    const q = new URLSearchParams({
      device_id: deviceId, format: 'json', limit: '5000', after_seq: String(after),
      from: String(fromTs), columns: DASH_COLUMNS,
    });
    const json = await call(`/api/v3/readings?${q}`);
    rows = rows.concat(json.readings || []);
    if (json.next_after_seq == null) break;
    after = json.next_after_seq;
  }
  return rows;
}

async function fetchPhotos(deviceId, fromTs, limit = 2000) {
  const q = new URLSearchParams({ device_id: deviceId, from: String(fromTs), limit: String(limit) });
  return (await call(`/api/v3/photos?${q}`)).photos || [];
}

function photoUrl(deviceId, path) {
  const q = new URLSearchParams({ device_id: deviceId, path, token: getToken() });
  return `/api/v3/photo?${q}`;
}

function csvUrl(deviceId, fromTs) {
  const q = new URLSearchParams({ device_id: deviceId, token: getToken() });
  if (fromTs) q.set('from', String(fromTs));
  return `/api/v3/readings?${q}`;
}

async function setInterval_(deviceId, minutes) {
  return call('/api/v3/devices/config', {
    method: 'PUT',
    body: JSON.stringify({ device_id: deviceId, measure_interval_minutes: minutes }),
  });
}

Object.assign(window, {
  AS_API: {
    getToken, setToken, AuthError, fetchDevices, fetchReadings, fetchPhotos, photoUrl, csvUrl,
    setInterval: setInterval_,
  },
});
