const config = require("./config");

class ApiClient {
  constructor(wallet) {
    this.wallet = wallet;
    this.token = null;
  }

  async request(method, path, body, { auth = true, timeoutMs = 15000 } = {}) {
    const headers = { "Content-Type": "application/json" };
    if (auth && this.token) headers.Authorization = `Bearer ${this.token}`;

    const ctrl = new AbortController();
    const tid = setTimeout(() => ctrl.abort(), timeoutMs);
    let res;
    try {
      res = await fetch(`${config.apiUrl}${path}`, {
        method,
        headers,
        body: body ? JSON.stringify(body) : undefined,
        signal: ctrl.signal
      });
    } catch (err) {
      // Antes este fallo de red (DNS, conexion rechazada, timeout) solo se
      // veia en el catch generico del llamador (p.ej. "[heartbeat] error: ..."),
      // sin indicar a que endpoint ni con que URL exacta se intento conectar —
      // clave quando la causa es EUROTRANS_API_URL mal resuelto (ver
      // project_launcher_cwd_bug en memoria: cae a 127.0.0.1:4000 si el .env
      // no se encuentra al arrancar).
      console.warn(`[api] ${method} ${path} -> fallo de red contra ${config.apiUrl}${path}: ${err.message}`);
      throw err;
    } finally {
      clearTimeout(tid);
    }

    const data = await res.json().catch(() => ({}));
    if (!res.ok) {
      console.warn(`[api] ${method} ${path} -> HTTP ${res.status}: ${data.error || res.statusText}`);
      throw new Error(`${method} ${path} -> ${res.status}: ${data.error || res.statusText}`);
    }
    return data;
  }

  heartbeat({ steamOnline = true, ets2Online = true } = {}) {
    return this.request("POST", "/heartbeat", {
      wallet: this.wallet.address.toLowerCase(),
      steam_online: steamOnline,
      ets2_online: ets2Online,
      launcher_version: config.launcherVersion
    });
  }

  getAvailableContracts(destination = null) {
    const wallet = this.wallet.address.toLowerCase();
    const dest = destination ? `&destination=${encodeURIComponent(destination)}` : "";
    return this.request("GET", `/contracts?wallet=${wallet}${dest}`);
  }

  claimContract(origin, destination, cargo = null, plannedDistanceKm = null, jobIncome = null) {
    return this.request("POST", "/contract/claim", {
      wallet: this.wallet.address.toLowerCase(),
      origin,
      destination,
      cargo:               cargo || undefined,
      planned_distance_km: plannedDistanceKm > 0 ? plannedDistanceKm : undefined,
      job_income:          jobIncome > 0 ? jobIncome : undefined
    });
  }

  acceptContract(contractId) {
    return this.request("POST", "/contract/accept", {
      wallet: this.wallet.address.toLowerCase(),
      contract_id: contractId
    });
  }

  cancelContract(contractId) {
    return this.request("POST", "/contract/cancel", {
      wallet: this.wallet.address.toLowerCase(),
      contract_id: contractId
    });
  }

  abandonContract() {
    return this.request("POST", "/player/contract/abandon", {
      wallet: this.wallet.address.toLowerCase()
    });
  }

  sendTelemetry(sample) {
    return this.request("POST", "/telemetry", {
      wallet:          this.wallet.address.toLowerCase(),
      speed:           sample.speed,
      fuel:            sample.fuelPercent,
      damage:          sample.damagePercent,         // máx(camión, remolque)
      damage_cabin:    sample.wearCabin,             // % cabina
      damage_truck:    sample.truckDamagePercent,    // peor componente camión
      damage_trailer:  sample.trailerDamagePercent,  // % remolque
      city:            sample.city,
      destination:     sample.destination,
      cargo:           sample.cargo,
      distance_km:     sample.distanceDrivenKm,
      remaining_km:    sample.remainingKm,
      deadline_minutes_left: sample.jobDeadlineMinutesLeft,
      truck_brand:     sample.truckBrand   || null,
      truck_model:     sample.truckModel   || null,
      truck_id:        sample.truckId      || null,
      trailer_name:    sample.trailerName  || null,
      trailer_id:      sample.trailerId    || null,
      fines:           sample.fines        || null
    });
  }
}

module.exports = { ApiClient };
