// api.jsx — Cliente HTTP del backend + mappers back↔front.

// ── Detección automática de la raíz de la app ────────────────────────
// Funciona idéntico en local (/Sistem_Ticke/...) y en producción (root /...)
// sin cambios. Lee el pathname actual y separa "lo de antes de /views/".
//
//   /Sistem_Ticke/views/admin/index.html  → APP_BASE = "/Sistem_Ticke"
//   /views/admin/index.html               → APP_BASE = ""
//   /tickets/views/index.html             → APP_BASE = "/tickets"
const APP_BASE = (() => {
  const m = location.pathname.match(/^(.*?)\/views\//);
  return m ? m[1] : "";
})();
const API_BASE   = APP_BASE + "/public";
const ASSET_BASE = APP_BASE + "/views/assets";

// ── Conversión de estado: front usa "proceso", backend usa "en proceso" ────
function estadoFrontToBack(estado) {
  return estado === "proceso" ? "en proceso" : estado;
}
function estadoBackToFront(estado) {
  return estado === "en proceso" ? "proceso" : estado;
}

// ── Mapper de un row de ticket_archivos del backend ────────────────────────
function mapArchivo(a) {
  const name    = a.archivo;
  const isImage = /\.(png|jpe?g|gif|webp|bmp|svg)$/i.test(name);
  const isVideo = /\.(mp4|webm|mov|m4v|ogv)$/i.test(name);
  return {
    id:    a.id != null ? Number(a.id) : null,
    name:  a.nombre_original || name,
    file:  name,
    type:  isImage ? "image" : isVideo ? "video" : "file",
    size:  Number(a.tamano || 0),
    url:   `${API_BASE}/uploads/${encodeURIComponent(name)}`,
  };
}

// ── Mapper de un row de ticket del backend al shape que esperan las vistas ─
function mapTicket(row) {
  if (!row) return null;
  const archivos = Array.isArray(row.archivos) ? row.archivos.map(mapArchivo) : [];
  const estadoFront = estadoBackToFront(row.estado);
  return {
    id:           row.codigo_ticket,
    _dbId:        Number(row.id),
    cliente:      row.nombre_cliente,
    celular:      row.celular_cliente,
    prioridad:    row.prioridad,
    proyecto:     row.nombre_proyecto || "",
    _proyectoId:  row.proyecto_id ? Number(row.proyecto_id) : null,
    descripcion:  row.descripcion,
    archivos,
    estado:       estadoFront,
    fecha:        (row.created_at || "").replace(" ", "T"),
    cerradoEn:    estadoFront === "finalizado" ? (row.updated_at || "").replace(" ", "T") : undefined,
  };
}

function mapProyecto(row) {
  return {
    id: Number(row.id),
    nombre_proyecto: row.nombre_proyecto,
    whatsapp_group_id: row.whatsapp_group_id || "",
  };
}

// ── Wrapper fetch JSON ────────────────────────────────────────────────────
async function jsonRequest(method, path, body) {
  const opts = {
    method,
    headers: {},
    credentials: "same-origin",   // enviar cookies de sesión
  };
  if (body !== undefined && !(body instanceof FormData)) {
    opts.headers["Content-Type"] = "application/json";
    opts.body = JSON.stringify(body);
  } else if (body instanceof FormData) {
    opts.body = body;
  }
  let res;
  try {
    res = await fetch(API_BASE + path, opts);
  } catch (e) {
    throw new Error("No se pudo contactar al servidor");
  }

  // Si la sesión expiró o no hay login, redirige al login del admin
  if (res.status === 401 && location.pathname.includes("/admin")) {
    location.replace("login.html");
    return;
  }

  let json = null;
  try { json = await res.json(); } catch (_) {}
  if (!res.ok || !json || json.ok === false) {
    const msg = (json && json.message) || `HTTP ${res.status}`;
    const err = new Error(msg);
    err.errors = json && json.errors;
    err.status = res.status;
    throw err;
  }
  return json.data;
}

// ── API pública ───────────────────────────────────────────────────────────
const api = {
  async listActive() {
    const rows = await jsonRequest("GET", "/tickets");
    return rows.map(mapTicket);
  },
  async listArchived() {
    const rows = await jsonRequest("GET", "/tickets/finalizados");
    return rows.map(mapTicket);
  },
  async createTicket(data) {
    const fd = new FormData();
    fd.append("nombre_cliente",  data.cliente);
    fd.append("celular_cliente", data.celular);
    fd.append("prioridad",       data.prioridad);
    fd.append("proyecto_id",     String(data.proyecto_id));
    fd.append("descripcion",     data.descripcion);
    if (Array.isArray(data.archivos)) {
      data.archivos.forEach(a => {
        if (a && a.file) fd.append("archivos[]", a.file, a.name);
      });
    }
    const row = await jsonRequest("POST", "/tickets", fd);
    return mapTicket(row);
  },
  async changeStatus(dbId, frontEstado, comentario) {
    const body = { estado: estadoFrontToBack(frontEstado) };
    if (comentario) body.comentario = comentario;
    const row = await jsonRequest("PATCH", `/tickets/${dbId}/estado`, body);
    return mapTicket(row);
  },
  async deleteTicket(dbId) {
    await jsonRequest("DELETE", `/tickets/${dbId}`);
    return true;
  },

  async listProjects() {
    const rows = await jsonRequest("GET", "/proyectos");
    return rows.map(mapProyecto);
  },
  async createProject(nombre, groupId) {
    const payload = { nombre_proyecto: nombre };
    if (groupId !== undefined) payload.whatsapp_group_id = groupId;
    const row = await jsonRequest("POST", "/proyectos", payload);
    return mapProyecto(row);
  },
  async updateProject(id, data) {
    const row = await jsonRequest("PUT", `/proyectos/${id}`, data);
    return mapProyecto(row);
  },
  async updateProjectGroup(id, groupId) {
    const data = await jsonRequest("PUT", `/proyectos/${id}/group`, { whatsapp_group_id: groupId });
    return data && data.whatsapp_group_id != null ? data.whatsapp_group_id : groupId;
  },
  async deleteProject(id) {
    await jsonRequest("DELETE", `/proyectos/${id}`);
    return true;
  },

  // ─── Auth (solo admin) ────────────────────────────────────────────────
  async me() {
    return jsonRequest("GET", "/auth/me");
  },
  async logout() {
    return jsonRequest("POST", "/auth/logout");
  },
  async changePassword(currentPassword, newPassword) {
    return jsonRequest("POST", "/auth/password", {
      current_password: currentPassword,
      new_password:     newPassword,
    });
  },

  // ─── Settings (solo admin) ────────────────────────────────────────────
  async getAdminPhone() {
    const data = await jsonRequest("GET", "/settings/admin-phone");
    return data && data.admin_phone ? data.admin_phone : "";
  },
  async updateAdminPhone(phone) {
    const data = await jsonRequest("PUT", "/settings/admin-phone", { admin_phone: phone });
    return data && data.admin_phone ? data.admin_phone : phone;
  },
  async getAdminNotify() {
    const data = await jsonRequest("GET", "/settings/admin-notify");
    return !!(data && data.admin_notify);
  },
  async updateAdminNotify(enabled) {
    const data = await jsonRequest("PUT", "/settings/admin-notify", { admin_notify: !!enabled });
    return !!(data && data.admin_notify);
  },
  async getWahaNumber() {
    return jsonRequest("GET", "/settings/waha-number");
  },
};

Object.assign(window, {
  api, API_BASE, APP_BASE, ASSET_BASE,
  mapTicket, mapProyecto, mapArchivo,
  estadoFrontToBack, estadoBackToFront,
});
