'use strict';

const telemetry = require('../../wall-e/telemetry');

const DEFAULT_FEEDBACK_URL = process.env.CTM_FEEDBACK_URL
  || process.env.WALLE_FEEDBACK_URL
  || 'https://create-walle.fly.dev/api/wall-e/feedback/submit';

const DEFAULT_TELEMETRY_URL = process.env.CTM_TELEMETRY_URL
  || process.env.WALLE_TELEMETRY_URL
  || 'https://create-walle.fly.dev/api/wall-e/telemetry/ingest';

function endpoint() {
  return process.env.CTM_FEEDBACK_URL
    || process.env.WALLE_FEEDBACK_URL
    || DEFAULT_FEEDBACK_URL;
}

function telemetryEndpoint() {
  return process.env.CTM_TELEMETRY_URL
    || process.env.WALLE_TELEMETRY_URL
    || DEFAULT_TELEMETRY_URL;
}

function buildEnvelope(feedback) {
  const envelope = {
    id: telemetry.getInstallId(),
    machine: telemetry.getMachineBucket(),
    v: telemetry.getVersion(),
    os: process.platform,
    node: process.version,
    feedback,
  };
  const user = telemetry.getTelemetryUser();
  if (user) envelope.user = user;
  return envelope;
}

function buildTelemetryEnvelope(event, meta = {}) {
  const envelope = {
    id: telemetry.getInstallId(),
    machine: telemetry.getMachineBucket(),
    v: telemetry.getVersion(),
    os: process.platform,
    node: process.version,
    events: [{
      e: String(event || 'ctm_event'),
      m: meta || {},
      t: Date.now(),
    }],
  };
  const user = telemetry.getTelemetryUser();
  if (user) envelope.user = user;
  return envelope;
}

function isFeedbackDisabled() {
  const value = String(process.env.CTM_FEEDBACK || '').toLowerCase();
  return value === '0' || value === 'false';
}

function isTelemetryDisabled() {
  const value = String(process.env.CTM_TELEMETRY || '').toLowerCase();
  return value === '0' || value === 'false';
}

async function submitFeedback(feedback, options = {}) {
  if (isFeedbackDisabled()) {
    return { ok: false, skipped: true, reason: 'feedback_disabled' };
  }
  const fetchImpl = options.fetchImpl || global.fetch;
  if (typeof fetchImpl !== 'function') {
    return { ok: false, skipped: true, reason: 'fetch_unavailable' };
  }
  const url = options.url || endpoint();
  const body = buildEnvelope(feedback);
  const controller = typeof AbortController === 'function' ? new AbortController() : null;
  let timer = null;
  if (controller) {
    timer = setTimeout(() => controller.abort(), Number(options.timeoutMs || 10000));
    if (typeof timer.unref === 'function') timer.unref();
  }
  try {
    const res = await fetchImpl(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body),
      signal: controller?.signal,
    });
    const json = await res.json().catch(() => ({}));
    if (!res.ok || json.ok === false) {
      return { ok: false, status: res.status, error: json.error || `HTTP ${res.status}` };
    }
    return { ok: true, status: res.status, ...json };
  } catch (err) {
    return { ok: false, error: err.name === 'AbortError' ? 'timeout' : err.message };
  } finally {
    if (timer) clearTimeout(timer);
  }
}

async function submitTelemetryEvent(event, meta = {}, options = {}) {
  if (isTelemetryDisabled()) {
    return { ok: false, skipped: true, reason: 'telemetry_disabled' };
  }
  const fetchImpl = options.fetchImpl || global.fetch;
  if (typeof fetchImpl !== 'function') {
    return { ok: false, skipped: true, reason: 'fetch_unavailable' };
  }
  const url = options.url || telemetryEndpoint();
  const body = buildTelemetryEnvelope(event, meta);
  const controller = typeof AbortController === 'function' ? new AbortController() : null;
  let timer = null;
  if (controller) {
    timer = setTimeout(() => controller.abort(), Number(options.timeoutMs || 10000));
    if (typeof timer.unref === 'function') timer.unref();
  }
  try {
    const res = await fetchImpl(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body),
      signal: controller?.signal,
    });
    const json = await res.json().catch(() => ({}));
    if (!res.ok || json.ok === false) {
      return { ok: false, status: res.status, error: json.error || `HTTP ${res.status}` };
    }
    return { ok: true, status: res.status, ...json };
  } catch (err) {
    return { ok: false, error: err.name === 'AbortError' ? 'timeout' : err.message };
  } finally {
    if (timer) clearTimeout(timer);
  }
}

module.exports = {
  buildEnvelope,
  buildTelemetryEnvelope,
  endpoint,
  telemetryEndpoint,
  isFeedbackDisabled,
  isTelemetryDisabled,
  submitFeedback,
  submitTelemetryEvent,
};
