#include "volume_control.h"
#include "webrtcpush_log.h"

#include <libsoup/soup.h>
#include <json-glib/json-glib.h>
#include <math.h>

/*
 * 定时拉取后端音量接口并设置到 AudioSink。
 *
 * 接口：GET https://fcrs-api.yd-ss.com/api/drive/use/status/{vehicleId}
 * 响应 JSON 中 businessJson 是字符串（需二次解析），取 volume 字段（0~1）。
 * businessJson 可能出现在 data.businessJson / data.data.businessJson / data.result.businessJson。
 * 每 3 秒拉一次，与手机端逻辑对齐。
 */
#define VC_INTERVAL_SEC      3
#define VC_DEFAULT_VOLUME    0.5
#define VC_VOLUME_EPSILON    0.001   /* 音量变化阈值，避免重复设置 */
#define VC_HTTP_TIMEOUT_SEC  5
#define VC_API_BASE          "https://fcrs-api.yd-ss.com/api/drive/use/status/"

struct VolumeControl {
  gchar *vehicle_id;
  AudioSink *sink;
  SoupSession *session;
  GThread *thread;
  gint stop;                /* 原子停止标志 */
  gdouble current_volume;
};

/*
 * 在 JsonObject 中查找 businessJson 字符串。
 * 兼容 data.businessJson / data.data.businessJson / data.result.businessJson
 * 以及顶层直接 businessJson 的情况。
 */
static const gchar *find_business_json(JsonObject *obj)
{
  JsonNode *node;
  JsonObject *child;

  if (!obj)
    return NULL;

  /* 顶层 businessJson */
  if (json_object_has_member(obj, "businessJson"))
    return json_object_get_string_member(obj, "businessJson");

  /* data.* */
  if (json_object_has_member(obj, "data")) {
    node = json_object_get_member(obj, "data");
    if (JSON_NODE_HOLDS_OBJECT(node)) {
      child = json_node_get_object(node);
      if (json_object_has_member(child, "businessJson"))
        return json_object_get_string_member(child, "businessJson");
      /* data.data.businessJson */
      if (json_object_has_member(child, "data")) {
        JsonNode *n2 = json_object_get_member(child, "data");
        if (JSON_NODE_HOLDS_OBJECT(n2)) {
          JsonObject *c2 = json_node_get_object(n2);
          if (json_object_has_member(c2, "businessJson"))
            return json_object_get_string_member(c2, "businessJson");
        }
      }
      /* data.result.businessJson */
      if (json_object_has_member(child, "result")) {
        JsonNode *n2 = json_object_get_member(child, "result");
        if (JSON_NODE_HOLDS_OBJECT(n2)) {
          JsonObject *c2 = json_node_get_object(n2);
          if (json_object_has_member(c2, "businessJson"))
            return json_object_get_string_member(c2, "businessJson");
        }
      }
    }
  }

  /* result.businessJson */
  if (json_object_has_member(obj, "result")) {
    node = json_object_get_member(obj, "result");
    if (JSON_NODE_HOLDS_OBJECT(node)) {
      child = json_node_get_object(node);
      if (json_object_has_member(child, "businessJson"))
        return json_object_get_string_member(child, "businessJson");
    }
  }

  return NULL;
}

/* 从 HTTP 响应体解析音量，范围 0~1。失败返回 -1.0 */
static gdouble parse_volume_from_response(const gchar *body, gsize len)
{
  JsonParser *parser;
  JsonNode *root;
  JsonObject *obj;
  const gchar *biz_json;
  gdouble volume = -1.0;
  GError *err = NULL;

  parser = json_parser_new();
  if (!json_parser_load_from_data(parser, body, len, &err)) {
    my_zlog_warn("volume_control: parse outer JSON failed: %s",
        err ? err->message : "unknown");
    if (err)
      g_error_free(err);
    g_object_unref(parser);
    return -1.0;
  }

  root = json_parser_get_root(parser);
  if (!root || !JSON_NODE_HOLDS_OBJECT(root)) {
    g_object_unref(parser);
    return -1.0;
  }
  obj = json_node_get_object(root);

  biz_json = find_business_json(obj);
  if (!biz_json || !biz_json[0]) {
    g_object_unref(parser);
    return -1.0;
  }

  /* businessJson 是 JSON 字符串，二次解析取 volume */
  {
    JsonParser *p2 = json_parser_new();
    JsonNode *root2;
    if (!json_parser_load_from_data(p2, biz_json, -1, &err)) {
      my_zlog_warn("volume_control: parse businessJson failed: %s",
          err ? err->message : "unknown");
      if (err)
        g_error_free(err);
      g_object_unref(p2);
      g_object_unref(parser);
      return -1.0;
    }
    root2 = json_parser_get_root(p2);
    if (root2 && JSON_NODE_HOLDS_OBJECT(root2)) {
      JsonObject *bobj = json_node_get_object(root2);
      if (json_object_has_member(bobj, "volume")) {
        JsonNode *vn = json_object_get_member(bobj, "volume");
        if (!json_node_is_null(vn))
          volume = json_node_get_double(vn);
      }
    }
    g_object_unref(p2);
  }

  g_object_unref(parser);
  return volume;
}

static void fetch_and_apply_volume(VolumeControl *vc)
{
  SoupMessage *msg;
  gchar *url;
  guint status;
  const gchar *body;
  gsize body_len;
  gdouble vol;

  url = g_strdup_printf("%s%s", VC_API_BASE, vc->vehicle_id);
  msg = soup_message_new("GET", url);
  if (!msg) {
    my_zlog_warn("volume_control: failed to create request for %s", url);
    g_free(url);
    return;
  }

  status = soup_session_send_message(vc->session, msg);

  if (status != 200) {
    my_zlog_warn("volume_control: HTTP %u for %s", status, url);
    g_object_unref(msg);
    g_free(url);
    return;
  }

  body = msg->response_body->data;
  body_len = msg->response_body->length;
  if (!body || body_len == 0) {
    my_zlog_warn("volume_control: empty response body for %s", url);
    g_object_unref(msg);
    g_free(url);
    return;
  }

  vol = parse_volume_from_response(body, body_len);
  if (vol < 0.0) {
    my_zlog_warn("volume_control: volume not found in response");
  } else if (fabs(vol - vc->current_volume) > VC_VOLUME_EPSILON) {
    /* 音量有变化才设置并记日志，避免噪音 */
    audio_sink_set_volume(vc->sink, vol);
    vc->current_volume = vol;
    my_zlog_info("volume_control: volume set to %.3f", vol);
  }

  g_object_unref(msg);
  g_free(url);
}

static gpointer volume_control_thread(gpointer data)
{
  VolumeControl *vc = data;

  while (g_atomic_int_get(&vc->stop) == 0) {
    fetch_and_apply_volume(vc);
    /* 分段睡眠（3s = 30 * 100ms），便于快速响应停止 */
    for (gint i = 0; i < VC_INTERVAL_SEC * 10; i++) {
      if (g_atomic_int_get(&vc->stop) != 0)
        break;
      g_usleep(100 * 1000); /* 100ms */
    }
  }
  return NULL;
}

VolumeControl *volume_control_start(const char *vehicle_id, AudioSink *sink)
{
  VolumeControl *vc;

  if (!vehicle_id || !vehicle_id[0] || !sink) {
    my_zlog_error("volume_control: invalid args");
    return NULL;
  }

  vc = g_new0(VolumeControl, 1);
  vc->vehicle_id = g_strdup(vehicle_id);
  vc->sink = sink;
  vc->current_volume = VC_DEFAULT_VOLUME;
  vc->stop = 0;

  /* 启动时先设默认音量 0.5 */
  audio_sink_set_volume(sink, VC_DEFAULT_VOLUME);

  /* libsoup 同步 session + HTTP 超时（部分版本不支持 async 属性，用 soup_session_new 兜底） */
  vc->session = soup_session_new();
  if (vc->session) {
    GParamSpec *pspec;
    pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(vc->session), "timeout");
    if (pspec)
      g_object_set(vc->session, "timeout", (guint)VC_HTTP_TIMEOUT_SEC, NULL);
    pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(vc->session), "idle-timeout");
    if (pspec)
      g_object_set(vc->session, "idle-timeout", (guint)VC_HTTP_TIMEOUT_SEC, NULL);
  }

  vc->thread = g_thread_new("volume-control", volume_control_thread, vc);

  my_zlog_info("volume_control: started vehicle_id=%s interval=%ds",
      vehicle_id, VC_INTERVAL_SEC);
  return vc;
}

void volume_control_stop(VolumeControl *vc)
{
  if (!vc)
    return;
  g_atomic_int_set(&vc->stop, 1);
  if (vc->thread)
    g_thread_join(vc->thread);
  if (vc->session)
    g_object_unref(vc->session);
  g_free(vc->vehicle_id);
  g_free(vc);
}
