#include "common.h"
#include "audioplay.h"
#include "device_identity.h"
#include "mqtt_init.h"
#include "http_config_mqtt.h"
#include "audiotts_play.h"

static int s_audio_status=7;
static char s_urlbuf[512];
static char s_keybuf[256];
static double s_audio_volume=0.8;

static double audioplay_volume_clamp(double v) {
	if (v < 0.0) {
		return 0.0;
	}
	if (v > 2.0) {
		return 2.0;
	}
	return v;
}

int audio_wheat_init();

//接收音频播放
void audioplay_mqtt_receive(cJSON *json) {
    // 解析"audioLink"字段（修正了原始JSON中的拼写错误）
    cJSON *audio_link = cJSON_GetObjectItemCaseSensitive(json, "audioLink");
    if (cJSON_IsString(audio_link) && (audio_link->valuestring != NULL)) {
        my_zlog_debug("音频链接: %s", audio_link->valuestring);
        char *url=audio_link->valuestring;
        snprintf(s_urlbuf, sizeof(s_urlbuf), "%s", url);
    } else {
        my_zlog_warn("错误：无法解析音频链接字段");
    }

    // 解析"key"字段
    cJSON *key_char = cJSON_GetObjectItemCaseSensitive(json, "key");
    if (cJSON_IsString(key_char) && (key_char->valuestring != NULL)) {
        my_zlog_debug("音频链接KEY: %s", key_char->valuestring);
        char *key=key_char->valuestring;
        snprintf(s_keybuf, sizeof(s_keybuf), "%s", key);
    } else {
        my_zlog_warn("错误：无法解析音频链接");
        s_audio_status=5;
    }

    // 解析"status"字段
    cJSON *s_audio_status_val = cJSON_GetObjectItemCaseSensitive(json, "status");
    if (cJSON_IsNumber(s_audio_status_val)) {
        my_zlog_debug("标志: %d", s_audio_status_val->valueint);
        s_audio_status=s_audio_status_val->valueint;
    } else {
        my_zlog_warn("错误：无法解析标志字段");
    }

    // 解析"volume"字段
    cJSON *volume = cJSON_GetObjectItemCaseSensitive(json, "volume");
    if (cJSON_IsNumber(volume)) {
        my_zlog_debug("声量大小: %.3f", volume->valuedouble);
        s_audio_volume = audioplay_volume_clamp(volume->valuedouble);
    } else {
        my_zlog_warn("错误：无法解析声量字段");
    }
}  

//发送音频播放是否完毕
void  audioplay_send_mqtt() {
    cJSON *root = cJSON_CreateObject();
    cJSON *body = cJSON_CreateObject();
    cJSON *head = cJSON_CreateObject();
        // 添加各个字段到 JSON 对象
    cJSON_AddStringToObject(body, "type", "audio");
    cJSON_AddStringToObject(body, "audioLink", s_urlbuf);
    cJSON_AddStringToObject(body, "key", s_keybuf);
    cJSON_AddNumberToObject(body, "status", s_audio_status);
    cJSON_AddNumberToObject(body, "volume", s_audio_volume);

    cJSON_AddNumberToObject(head, "message_type",3001);

    cJSON_AddItemToObject(root, "body", body);
    cJSON_AddItemToObject(root, "head",head);
    // 将 JSON 对象转换为字符串
    char* json_string = cJSON_PrintUnformatted(root);
    my_zlog_debug("%s",json_string);

    for(int i=0;i<g_mqtt_cam_config_t->mqtt_count;i++){
            mosquitto_publish(g_clients_t[i].mosq, NULL, mqtt_topic_pure_number(), strlen(json_string), json_string, 0, false); 
        } 
    free(json_string);
    cJSON_Delete(root);
}

//音频播放
void audioplay_cycle(){
    char command[1024];
    int ret;
    while(1){
        if(s_audio_status==0){

            char *urlmoddle=s_urlbuf;
            s_audio_volume = audioplay_volume_clamp(s_audio_volume);
            snprintf(command, sizeof(command),
            "sudo ffplay -nodisp -autoexit -loglevel quiet -af \"volume=%.3f\" \"%s\"",
            s_audio_volume,urlmoddle);

            my_zlog_debug("播放地址: %s", s_urlbuf);
            my_zlog_info("执行播放命令: %s", command);
            ret = system(command);
            if (ret != 0) {
                my_zlog_error("播放失败");
                s_audio_status=2;
            }

            if (WIFEXITED(ret) && WEXITSTATUS(ret) == 0) {
                my_zlog_debug("播放已成功完成 : %s ", s_urlbuf);  
                s_audio_status=1;   
            } else {
                my_zlog_warn("播放失败或中断: %s ", s_urlbuf);
                s_audio_status=2;
            }
        audioplay_send_mqtt();
        }

        video_tts_play();

        delay_ms(100);
    
    }
}

int audio_wheat_init(){
    int adino_jude = system("pactl load-module module-alsa-sink device=hw:2,0");
    if(adino_jude  == 0 ){
        my_zlog_debug("命令执行成功！");
        return 0;
    }else {
        if(adino_jude  != 0) my_zlog_warn("喇叭命令执行失败，返回状态码: %d", adino_jude );
        return -1;
    }
}

int audio_speaker_init() {

    int adino_play_jude =system("pactl load-module module-alsa-source device=hw:2,0");
    
    if ( adino_play_jude==0 ) {
        my_zlog_debug("命令执行成功！");
        return 0;
    } else {
        if(adino_play_jude!=0) my_zlog_warn("麦命令执行失败，返回状态码: %d", adino_play_jude );
        return -1;
    }
}

int audio_init(){

    delay_s(10);
    audio_wheat_init();
    delay_s(3);
    audio_speaker_init();

    return 0;
}


#define CONFIG_FILE "/usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf"

static const char *s_yundea_block =
"# 为 Yundea 1076 USB 二合一设备添加配置\n"
"[Mapping yundea-input]\n"
"device-strings = hw:%f,0\n"
"direction = input\n"
"priority = 100\n"
"channel-map = mono\n"
"\n"
"[Mapping yundea-output]\n"
"device-strings = hw:%f,0\n"
"direction = output\n"
"priority = 100\n"
"channel-map = left,right\n"
"\n"
"[Profile yundea-duplex]\n"
"input-mappings = yundea-input\n"
"output-mappings = yundea-output\n"
"priority = 200\n";

/*
*功能：加入usb声卡配置
*
*/
int audio_config_init() {

    delay_s(20);//延迟30s

    FILE *fp = fopen(CONFIG_FILE, "r");
    if (!fp) {
        perror("无法打开配置文件进行读取");
        return 1;
    }

    // 获取文件大小
    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    char *buffer = malloc(size + 1);
    if (!buffer) {
        my_zlog_error("内存分配失败");
        fclose(fp);
        return 1;
    }

    size_t result =fread(buffer, 1, size, fp);
    if (result != size) {
    my_zlog_warn("Error: Failed to read audio data");
    }
    buffer[size] = '\0';
    fclose(fp);

    // 检查是否包含完整配置块
    if (strstr(buffer, s_yundea_block) != NULL) {
        my_zlog_info("配置文件中已包含指定配置，跳过添加。");
        free(buffer);
        return 0;
    }

    free(buffer);

   my_zlog_info("未找到指定配置，正在追加到文件末尾...");

    // 打开文件追加配置
    fp = fopen(CONFIG_FILE, "a");
    if (!fp) {
        my_zlog_error("无法打开配置文件进行写入");
        return 1;
    }

    fprintf(fp, "\n%s", s_yundea_block);
    fclose(fp);

    my_zlog_info("配置已成功追加。");
    return 0;
}